سؤال

أريد تحليل سلسلة بحث مماثلة لتلك التي توفرها Gmail باستخدام Perl. سيكون إدخال مثال "علامة: شيء حسب: {User1 User2} {-tag: a بواسطة: user3}". أريد أن أضعها في هيكل شجرة، مثل

{and => [
    "tag:thing",
    {or => [
       "by:user1",
       "by:user2",
    ]},
    {or => [
       {not => "tag:a"},
       "by:user3",
    ]},
}

القواعد العامة هي:

  1. الرموز مفصولة عن طريق الفضاء الافتراضي للمشغل.
  2. الرموز في الأقواس خيارات بديلة (أو). يمكن أن تذهب الأقواس قبل أو بعد محدد الميدان. IE "بواسطة: {User1 User2}}" و "{by: user1 by: user2}" تعادل.
  3. يتم استبعاد الرموز البادئة مع واصلة.

يمكن أيضا دمج هذه العناصر وتخصيتها: على سبيل المثال "{بواسطة: user5 - {tag: k by: user3}} إلخ".

أفكر في كتابة قواعد قواعد خالية من السياق لتمثيل هذه القواعد، ثم تحليلها في الشجرة. هل هذا غير ضروري؟ (هل هذا ممكن باستخدام Regexps بسيطة؟)

ما هي الوحدات النمطية الموصى بها للقيام بتحليل النحو الخالي من السياق؟

(في النهاية، سيتم استخدام هذا لإنشاء استعلام قاعدة بيانات مع DBIX :: Class.)

هل كانت مفيدة؟

المحلول

لا يقوم Regex بأشياء متداخلة (مثل الأقواس) جيدا. بحلول الوقت الذي تحصل فيه على عد Regex الخاص بك بين قوسين وقم بالاستيلاء بشكل صحيح، ربما يكون لديك محلل CFG لائق. CFGS يمكن أن تضمن منطقيا التحليل الصحيح، بينما مع محلول Regex الذي تركت الكثير حتى السحر. لا أستطيع أن أوصي بأي Libaries Perl CFG، ولكن ترميز واحد يبدو كاديكيا للغاية.

نصائح أخرى

yapp. قد تفعل ما تريد. يمكنك استخدامه لتوليد Automaton Authating (1) ثم استخدامه.

إذا لم يكن الاستعلام الخاص بك منظم شجرة، فستفعل Regxes المهمة لك.

علي سبيل المثال:

my $search = "tag:thing by:{user1 user2} {-tag:a by:user3}"
my @tokens = split /(?![^{]*})\s+/, $search;
foreach (@tokens) {
    my $or = s/[{}]//g; # OR mode
    my ($default_field_specifier) = /(\w+):/;
}

حتى لو استفسارك يكون شجرة منظم، Regexes يمكن أن تجعل تحليل العودية أكثر متعة:

$_ = "by:{user1 z:{user2 3} } x {-tag:a by:user3} zz";
pos($_) = 0;
scan_query("");

sub scan_query {
    my $default_specifier = shift;
    while (/\G\s*((?:[-\w:]+)|(?={))({)?/gc) {
        scan_query($1), next if $2;
        my $query_token = $default_specifier . $1;
    }
    /\G\s*\}/gc;
}

Regexes رهيبة :)!

تحليل :: الركود يمكن أن تولد المحللين لهذا النوع من الأشياء. ربما تحتاج إلى بعض الخبرة مع المحللين لاستخدامها بشكل فعال على الرغم من ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top