मैच कैसे करें, लेकिन कब्जा नहीं, रेगेक्स का हिस्सा?


209

मेरे पास तार की एक सूची है। उनमें से कुछ फॉर्म के हैं 123-...456। चर भाग "..." हो सकता है:

  • स्ट्रिंग "सेब" एक हाइफ़न के बाद, उदाहरण के लिए 123-apple-456
  • स्ट्रिंग "केला" एक हाइफ़न के बाद, उदाहरण के लिए 123-banana-456
  • एक रिक्त स्ट्रिंग, उदाहरण के लिए 123-456(ध्यान दें कि केवल एक हाइफ़न है)

"सेब" या "केला" के अलावा कोई भी शब्द अमान्य है।

इन तीन मामलों के लिए, मैं क्रमशः "सेब", "केला" और "" से मेल खाना चाहूंगा। ध्यान दें कि मैं कभी भी हाइफ़न पर कब्जा नहीं करना चाहता , लेकिन मैं हमेशा इसे मैच करना चाहता हूं । यदि स्ट्रिंग 123-...456ऊपर वर्णित रूप में नहीं है, तो उसका कोई मेल नहीं है।

मैं ऐसा करने के लिए एक नियमित अभिव्यक्ति कैसे लिखूं? मान लें कि मेरे पास एक स्वाद है जो लुकहेड, लुकबाइंड, लुकअराउंड और गैर-कैप्चरिंग समूहों की अनुमति देता है।


यहाँ मुख्य अवलोकन यह है कि जब आपके पास "सेब" या "केला" होता है, तो आपके पास अनुगामी हाइफ़न भी होना चाहिए , लेकिन आप इसका मिलान नहीं करना चाहते हैं। और जब आप रिक्त स्ट्रिंग का मिलान कर रहे हों, तो आपके पास अनुगामी हाइफ़न नहीं होना चाहिए । मुझे लगता है कि इस दावे को समझने वाला एक रेग्क्स सही होगा।


आप हाइफ़न को छोड़कर सब कुछ मैच करना चाहते हैं?
ब्रूनोएलएम

जवाबों:


285

किसी चीज़ को कैप्चर नहीं करने का एकमात्र तरीका है लुक-अराउंड का उपयोग करना :

(?<=123-)((apple|banana)(?=-456)|(?=456))

क्योंकि गैर-कैप्चरिंग समूहों(?:…) के साथ भी पूरी नियमित अभिव्यक्ति उनकी मिलान की गई सामग्री को कैप्चर करती है। लेकिन यह नियमित अभिव्यक्ति केवल appleया bananaयदि इसके द्वारा 123-और इसके बाद से पहले से -456मेल खाती है , या यह इसके बाद और इसके बाद खाली स्ट्रिंग से मेल खाती 123-है 456

|Lookaround  |    Name      |        What it Does                       |
-----------------------------------------------------------------------
|(?=foo)     |   Lookahead  | Asserts that what immediately FOLLOWS the |
|            |              |  current position in the string is foo    |
-------------------------------------------------------------------------
|(?<=foo)    |   Lookbehind | Asserts that what immediately PRECEDES the|
|            |              |  current position in the string is foo    |
-------------------------------------------------------------------------
|(?!foo)     |   Negative   | Asserts that what immediately FOLLOWS the |
|            |   Lookahead  |  current position in the string is NOT foo|
-------------------------------------------------------------------------
|(?<!foo)    |   Negative   | Asserts that what immediately PRECEDES the|
|            |   Lookbehind |  current position in the string is NOT foo|
-------------------------------------------------------------------------

1
+1 - इस मामले में, आप समूह 0 के बजाय समूह 1 का उपयोग करके चारों ओर काम कर सकते हैं, लेकिन यह एक उत्कृष्ट (और सूक्ष्म!) भेद है।
बेन ब्लैंक

@बेन ब्लैंक: यह निश्चित रूप से इस बात पर निर्भर करता है कि "मैच" और "कैप्चर" की व्याख्या कैसे की जाती है।
गमबो

8
जावास्क्रिप्ट में समर्थित नहीं है, याय ! एक जेएस के अनुकूल तरीका होना अच्छा होगा, लेकिन खराब बिल्कुल नहीं, +0.5 (राउंडिंग डी; डी)
जाइंटकॉफिल्म्स

प्यार देखो चारों ओर जोर! रूबी के साथ भी ये बेहतरीन हैं।
रॉट्स

सही समाधान, मुझे यह पसंद है
Trần Quang Hi Mayp

15

अपडेट: जर्मेन रॉड्रिग्ज हरेरा को धन्यवाद!

जावास्क्रिप्ट प्रयास में: /123-(apple(?=-)|banana(?=-)|(?!-))-?456/

याद रखें कि परिणाम समूह 1 में है

डीबगेजक्स डेमो


8

प्रयत्न:

123-(?:(apple|banana|)-|)456

यह मेल खाएगा apple, bananaया एक रिक्त स्ट्रिंग, और इसके बाद एक 0 या 1 हाइफ़न होगा। मैं एक कैप्चरिंग ग्रुप की आवश्यकता नहीं होने के बारे में गलत था। मुझे मूर्ख।


यह सही नहीं है क्योंकि यह मेल खाता है, उदाहरण के लिए, "123-नारियल -456"।
डेविड स्टोन

सोचा था कि आप इसे और अधिक सामान्य चाहते थे ... तय किया।
थॉमस

5

मैंने उत्तरों में से एक को संशोधित किया है (@ op1ekun द्वारा):

123-(apple(?=-)|banana(?=-)|(?!-))-?456

कारण यह है कि @ op1ekun का उत्तर भी "123-apple456"सेब के बाद हाइफ़न के बिना, मेल खाता है ।


3

इसे इस्तेमाल करे:

/\d{3}-(?:(apple|banana)-)?\d{3}/

1
यह सही नहीं है क्योंकि यह मेल खाता है, उदाहरण के लिए, "123-नारियल -456"।
डेविड स्टोन

@ डेविड: यह आपके "केले" के उदाहरण से कैसे अलग है?
SilentGhost

@SilentGhost: मैं केवल कब्जा करना चाहते हैं appleया bananaया ""। अन्य सभी मूल्य अमान्य हैं, जैसा कि मैंने कहा।
डेविड स्टोन

sry, उस स्थिति में: / \ d {3} - (?: (सेब | केला) -)? \ d {3} /
slosd

1
इस उदाहरण से पता चलता है कि लुकहैड और लुकबाइंड का उपयोग किए बिना गैर-कैप्चरिंग समूह होना संभव है।
विंस पानुकियो

0

@Gumbo द्वारा अभिव्यक्ति की एक भिन्नता जो \Kमैच में नंबर ब्लॉक को शामिल करने से रोकने के लिए मैच की स्थिति को रीसेट करने के लिए उपयोग करती है । PCRE regex जायके में प्रयोग करने योग्य।

123-\K(?:(?:apple|banana)(?=-456)|456\K)

मेल खाता है:

Match 1  apple
Match 2  banana
Match 3

-3

अब तक सबसे सरल (अजगर के लिए काम करता है) है '123-(apple|banana)-?456'


1
यह मैच होगा 123-apple456इसलिए यह सही नहीं है।
लोरेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.