سؤال

أبحث عن قليلا من regex مساعدة.أود أن تصميم تعبير المباريات سلسلة مع "فو"أو "شريط"،ولكن ليس على حد سواء "فو"و "شريط"

إذا كنت تفعل شيئا مثل...

/((foo)|(bar))/

سوف المباراة "س".لا ما كنت أبحث عنه.كيف يمكنني جعل regex مباراة فقط عند مصطلح واحد أو الآخر هو الحاضر ؟

وذلك بفضل!

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

المحلول

ويمكنك القيام بذلك مع التعابير المنطقية واحد ولكن أقترح من أجل سهولة القراءة لديك شيء من هذا القبيل ...

(/foo/ and not /bar/) || (/bar/ and not /foo/)

نصائح أخرى

وهذا هو ما يمكنني استخدام:

/^(foo|bar){1}$/

وانظر: http://www.regular-expressions.info/quickstart.html في ظل تكرار

إذا لغة التعابير المنطقية الخاصة بك يعتمد عليه، استخدم سلبية استكشاف الأجواء المحيطة :

(?<!foo|bar)(foo|bar)(?!foo|bar)

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

وليس من الواضح من سؤالك أو أمثلة إذا كانت السلسلة التي تحاول تطابق يمكن أن تحتوي على الرموز الأخرى: "foocuzbar". إذا كان الأمر كذلك، فإن هذا النمط لا تعمل.

وهنا هي نتائج حالات الاختبار الخاص بك ( "الحقيقية" يعني تم العثور على النقش في المدخلات):

foo: true
bar: true
foofoo: false
barfoo: false
foobarfoo: false
barbar: false
barfoofoo: false

وهذا سيستغرق "فو" و "بار" وليس "foobar 'وليس' blafoo 'وليس' blabar ':

/^(foo|bar)$/

^ = mark start of string (or line)
$ = mark end of string (or line)

وهذا سيستغرق "فو" و "بار" و "البار فو" و "بار-فو" وليس "foobar 'وليس' blafoo 'وليس' blabar ':

/\b(foo|bar)\b/

\b = mark word boundry

لم يتم تحديد السلوك بشأن المحتوى من "فو" و "بار" أو التكرار من واحد في غياب الآخر.على سبيل المثال" ، فود" أو "باربارإيان" المباراة ؟

على افتراض أن كنت ترغب في مطابقة السلاسل التي تحتوي على مثيل واحد فقط إما "فو" أو "بار" ، ولكن ليس على حد سواء وليس مثيلات متعددة من نفس واحدة ، دون اعتبار لأي شيء آخر في السلسلة (أي "الغذاء" مباريات و "البربري" لا يطابق), ثم هل يمكن استخدام التعابير المنطقية التي تقوم بإرجاع عدد من المباريات وجدت فقط اعتبرها ناجحة إذا واحد بالضبط يتم العثور على تطابق.مثلا في بيرل:

@matches = ($value =~ /(foo|bar)/g)  # @matches now hold all foos or bars present
if (scalar @matches == 1) {          # exactly one match found
  ...
}

إذا كان التكرار متعددة من نفس الهدف مسموح بها (أي "البربري" مباريات) ، ثم نفس هذا النهج العام يمكن استخدامها من قبل ثم المشي قائمة المباريات لمعرفة ما إذا كان يتطابق كل يكرر نفس النص أو إذا كان الخيار الآخر هو أيضا موجودة.

وقد ترغب في النظر في؟ الاختبار الشرطي.

(?(?=regex)then|else)

التعبير منتظم الشرطية

إذا كنت ترغب في صحيح حصرية، أو كنت تفعل ذلك في التعليمات البرمجية بدلا من التعبير المعتاد. في بيرل:

/foo/ xor /bar/

ولكن تعليقك:

<اقتباس فقرة>   

ومباريات: "فو"، "شريط" nonmatches:   "FOOFOO" "barfoo" "foobarfoo" "بربر"   "barfoofoo"

ويشير إلى أن كنت لا تبحث حقا عن حصرية أو. تقصد فعلا "هل /foo|bar/ تتطابق تماما مرة واحدة؟"

my $matches = 0;
while (/foo|bar/g) {
  last if ++$matches > 1;
}

my $ok = ($matches == 1)

وأنا أعلم أن هذا هو الدخول في وقت متأخر، ولكن فقط لمساعدة الآخرين الذين يمكن ان تبحث:

(/b(?:(?:(?!foo)bar)|(?:(?!bar)foo))/b)

وكنت استخدام شيء من هذا القبيل. هو فقط بالتحقق من الفضاء حول الكلمات، ولكن هل يمكن استخدام \b أو \B للتحقق من الحدود إذا كنت تستخدم \w. هذا من شأنه أن تطابق "فو" أو "شريط"، حيث من الواضح أن عليك أن تحل محل بيضاء أيضا، فقط في حالة. (على افتراض انك تحل محل أي شيء.)

/\s((foo)|(bar))\s/

وأنا لا أعتقد أن هذا يمكن القيام به مع تعبير عادي واحد. والحدود قد أو قد لا تعمل اعتمادا على ما كنت مطابقة ضده.

وأود أن مباراة ضد كل التعابير المنطقية على حدة، والقيام XOR على النتائج.

foo = re.search("foo", str) != None
bar = re.search("bar", str) != None
if foo ^ bar:
    # do someting...

وحاولت مع التعبيرات المنتظمة المدرب ضد:

x foo y
x bar y
x foobar y

إذا كنت تحقق الخيار g، في الواقع يطابق كل الكلمات الثلاث، لأنه يبحث مرة أخرى بعد كل مباراة.
إذا كنت لا تريد هذه المشكلة، يمكنك ترسيخ التعبير، على سبيل المثال مطابقة فقط على حدود الكلمة:

\b(foo|bar)\b

وإعطاء مزيد من السياق حول المشكلة (ما تبدو البيانات مثل) قد يعطي إجابات أفضل.

\b(foo)\b|\b(bar)\b

واستخدم فقط مجموعة التقاط .

وباستخدام حدود الكلمة، يمكنك الحصول على كلمة واحدة ...

me@home ~  
$ echo "Where is my bar of soap?" | egrep "\bfoo\b|\bbar\b"  
Where is my bar of soap?  

me@home ~  
$ echo "What the foo happened here?" | egrep "\bfoo\b|\bbar\b"  
What the foo happened here?  

me@home ~  
$ echo "Boy, that sure is foobar\!" | egrep "\bfoo\b|\bbar\b"  
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top