سؤال

أحاول مطابقة العناصر التالية في السلسلة pcode:

  • u متبوعًا برقم مكون من رقم واحد أو رقمين
  • phaseu
  • phasep
  • x (محاط بأحرف غير كلمة)
  • y (محاط بأحرف غير كلمة)
  • z (محاط بأحرف غير كلمة)

لقد حاولت تنفيذ مطابقة regex باستخدام وظائف POSIX regex (الموضحة أدناه)، ولكن واجهت مشكلتين:

  1. يبدو أن النمط المترجم لا يحتوي على أنماط فرعية (أي.compiled.n_sub == 0).
  2. لم يجد النمط تطابقات في السلسلة "u0"، وهو ما ينبغي عليه فعله حقًا!

أنا واثق من أن سلسلة regex نفسها تعمل - حيث أنها تعمل في python وTextMate - مشكلتي تكمن في التجميع، وما إلى ذلك.شركة.أي مساعدة في الحصول على هذا العمل سيكون موضع تقدير كبير.

شكرا سلفا لاجاباتك.

if(idata=tb_find(deftb,pdata)){
    MESSAGE("Global variable!\n");
    char pattern[80] = "((u[0-9]{1,2})|(phaseu)|(phasep)|[\\W]+([xyz])[\\W]+)";
    MESSAGE("Pattern = \"%s\"\n",pattern);
    regex_t compiled;
    if(regcomp(&compiled, pattern, 0) == 0){
        MESSAGE("Compiled regular expression \"%s\".\n", pattern);
    }

    int nsub = compiled.re_nsub;
    MESSAGE("nsub = %d.\n",nsub);
    regmatch_t matchptr[nsub];
    int err;
    if(err = regexec (&compiled, pcode, nsub, matchptr, 0)){
        if(err == REG_NOMATCH){
            MESSAGE("Regular expression did not match.\n");
        }else if(err == REG_ESPACE){
            MESSAGE("Ran out of memory.\n");
        }
    }
    regfree(&compiled);
}
هل كانت مفيدة؟

المحلول

يبدو أنك تنوي استخدام شيء يشبه بناء جملة POSIX regex "الموسع".يعرّف POSIX تركيبين مختلفين من صيغ التعبير العادي، بناء الجملة "الأساسي" (اقرأ "قديم") وبناء الجملة "الموسع".لاستخدام بناء الجملة الموسع، تحتاج إلى إضافة REG_EXTENDED العلم ل regcomp:

...
if(regcomp(&compiled, pattern, REG_EXTENDED) == 0){
...

بدون هذه العلامة، سيستخدم regcomp بناء جملة regex "الأساسي".هناك بعض الاختلافات المهمة، مثل:

  • لا يوجد دعم لل | المشغل أو العامل
  • يجب الهروب من الأقواس الخاصة بالمطابقات الفرعية، \( و \)

وتجدر الإشارة أيضًا إلى ذلك إن بناء جملة POSIX الممتد regex غير متوافق 1:1 مع regex الخاص بـ Python (لا أعرف عن TextMate).على وجه الخصوص، أخشى أن هذا الجزء من التعبير العادي الخاص بك لا يعمل في POSIX، أو على الأقل غير محمول:

 [\\W]

طريقة POSIX لتحديد الأحرف غير الفضائية هي:

 [^[:space:]]

يجب أن يبدو التعبير العادي الخاص بك بالكامل لـ POSIX بهذا الشكل في لغة C:

 char *pattern = "((u[0-9]{1,2})|(phaseu)|(phasep)|[^[:space:]]+([xyz])[^[:space:]]+)";
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top