كيف يمكنني مطابقة نمط مع عروض الأسعار المحيطة الاختيارية؟

StackOverflow https://stackoverflow.com/questions/3568995

سؤال

كيف يمكن للمرء أن يكتب regex يطابق نمطًا يمكن أن يحتوي على علامات اقتباس ، ولكن إذا حدث ذلك ، يجب أن يكون له علامات اقتباس مطابقة في البداية والنهاية؟

"?(pattern)"?

لن تعمل لأنها ستسمح أنماطًا تبدأ باقتباس ولكن لا تنتهي بأحدها.

"(pattern)"|(pattern)

سوف تعمل ، ولكن متكررة. هل هناك طريقة أفضل للقيام بذلك دون تكرار النمط؟

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

المحلول

يمكنك الحصول على حل دون التكرار عن طريق الاستفادة من الخلفية و الشرطية:

/^(")?(pattern)(?(1)\1|)$/

اعواد الكبريت:

  • نمط
  • "نمط"

لا يتطابق:

  • "نمط
  • نمط"

هذا النمط معقد إلى حد ما. يبحث أولاً عن اقتباس اختياري ، ويضعه في الخلفية 1 إذا تم العثور على واحد. ثم يبحث عن نمطك. ثم يستخدم بناء جملة مشروط ليقول "إذا تم العثور على Backreference 1 مرة أخرى ، فطابقه ، وإلا تطابق لا شيء". النمط كله ترتكز (مما يعني أنه يحتاج إلى الظهور بمفرده على خط) حتى لا يتم التقاط علامات الاقتباس التي لا مثيل لها (وإلا pattern في pattern" سوف تطابق).

لاحظ أن دعم الشرطية يختلف حسب المحرك ، وسيتم دعم التعبيرات المتكررة بشكل أكبر ولكن من المحتمل أن يفهمها).


تحديث: نسخة أبسط بكثير من هذا regex ستكون /^(")?(pattern)\1$/, والتي لا تحتاج إلى شرطية. عندما كنت أختبر هذا في البداية ، أعطاني المختبر الذي كنت أستخدمه سلبية خاطئة ، مما دفعني إلى خصمه (عفوًا!).

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

نصائح أخرى

اعتمادًا على اللغة التي تستخدمها ، يجب أن تكون قادرًا على استخدام REARFERENCES. شيء من هذا القبيل ، قل:

(["'])(pattern)\1|^(pattern)$

وبهذه الطريقة ، أنت تتطلب إما عدم وجود علامات اقتباس ، أو أن الاقتباس نفسه يستخدم في كلا الطرفين.

يجب أن يعمل هذا مع Regex العودية (والذي يحتاج إلى وقت أطول للحصول على الصواب). في غضون ذلك: في بيرل, ، يمكنك بناء ملف إعادة تعديل ذاتي regex. سأترك ذلك كمثال أكاديمي ؛-)

my @stuff = ( '"pattern"', 'pattern', 'pattern"', '"pattern'  );

foreach (@stuff) {
   print "$_ OK\n" if /^
                        (")?
                        \w+
                        (??{defined $1 ? '"' : ''})
                       $
                      /x
}

نتيجة:

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