नियमित अभिव्यक्तियाँ: क्या कोई AND ऑपरेटर है?


707

जाहिर है, आप |प्रतिनिधित्व करने के लिए (पाइप?) का उपयोग कर सकते हैं OR, लेकिन क्या ANDसाथ ही साथ प्रतिनिधित्व करने का कोई तरीका है ?

विशेष रूप से, मैं पाठ के पैराग्राफों का मिलान करना चाहूंगा, जिनमें सभी एक निश्चित वाक्यांश के होते हैं, लेकिन किसी विशेष क्रम में नहीं।


1
क्या आपका मतलब है कि आप किसी पाठ में वाक्यांश ढूंढना चाहते हैं, जहां प्रत्येक ऐसा वाक्यांश किसी दिए गए वाक्यांश में शब्दों का एक मान्य क्रम है।
नीत्शे-जो

2
मैं इसे यहाँ रख रहा हूँ क्योंकि तीन या चार उत्तर इसे अनदेखा करते हैं। जब तक वे $ में समाप्त नहीं होते तब तक लाहदहेड प्रत्येक खंड के लिए समान लंबाई से मेल नहीं खाता। एक लुकहेड चार वर्णों से मेल खा सकता है, और दूसरा 6. उदाहरण के लिए, (? = A *) (? = Aab) aabaaaaba
Zachary Vance

2
"एंड" ऑपरेटर के लिए सिर्फ "स्पेस" चरित्र का उपयोग करने का प्रयास करें।

1 I'd like to match paragraphs of text.। 2. आउट-ऑफ-ऑर्डर पाठ से युक्त । नंबर 1 व्याख्या के लिए खुला है। नंबर 2 को कुछ तरीके से किया जा सकता है। रास्ता 1:, (?:(?:(?(1)(?!))\b(phrase1)\b.*?|(?(2)(?!))\b(phrase2)\b.*?)){2}रास्ता 2: (?=.*\bphrase1\b)(?=.*\bphrase2\b)जहाँ इस में, इस मामले में पैराग्राफ का मिलान अपरिभाषित है जब तक कि पैराग्राफ की परिभाषा औपचारिक नहीं हो जाती।

जवाबों:


385

गैर-खपत वाली नियमित अभिव्यक्ति का उपयोग करें।

विशिष्ट (यानी पर्ल / जावा) अंकन है:

(?=expr)

इस का अर्थ है "मैच expr लेकिन उसके बाद मूल मैच बिंदु पर मिलान रहे हैं।"

आप इनमें से जितने चाहें कर सकते हैं, और यह एक "और" होगा। उदाहरण:

(?=match this expression)(?=match this too)(?=oh, and this)

यदि आप डेटा में से कुछ को बचाने की आवश्यकता है, तो आप गैर-खपत अभिव्यक्तियों के अंदर कैप्चर समूह भी जोड़ सकते हैं।


3
perl -e "q {कुछ सामान और चीजें} = ~ / ((? = कुछ) (? = सामान) ((या चीजें) / /? प्रिंट 'हां': प्रिंट 'नहीं'" प्रिंट 'नहीं'।
राबर्ट पी।

27
यह उल्लेख किया जाना चाहिए कि इस विशेष उदाहरण को एक सकारात्मक रूपांतर कहा जाता है। इसके "और" के अलावा अन्य उपयोग हैं। ध्यान दें कि पाठ का उपभोग नहीं किया गया है।
strager

7
(? =) का उपयोग करना इस तरह एक परिणाम में है जो कभी सफल नहीं हो सकता। लेकिन यह है के संयोजन के रूप अनुरूप |। ओपी सिर्फ गलत है जो वह सोचता है कि उसकी समस्या का समाधान होगा।
नीत्शे-जौ २२'०१

10
perl -e "q {कुछ सामान और चीज़ें} = ~ /(?=.some))??=*stuff)(?=.thth))/? प्रिंट 'यस': प्रिंट 'नो'"
क्रिश

3
क्या आप अपने उत्तर में पर्ल कोड में कुछ आसान उदाहरण जोड़ सकते हैं?
पिथिकोस

343

लुकहेड का उपयोग करने की आवश्यकता है क्योंकि कुछ अन्य उत्तरदाताओं ने कहा है, लेकिन लुकहेड को इसके लक्ष्य शब्द और वर्तमान मैच की स्थिति के बीच अन्य पात्रों के लिए जिम्मेदार होना है। उदाहरण के लिए:

(?=.*word1)(?=.*word2)(?=.*word3)

.*पहले अग्रदर्शी में यह इससे पहले कि यह "WORD1" करने के लिए हो जाता है की जरूरत है हालांकि कई वर्णों से मेल की सुविधा देता है। फिर मैच की स्थिति रीसेट हो जाती है और दूसरा लुकहेड "वर्ड 2" ढूंढता है। फिर से रीसेट करें, और अंतिम भाग "वर्ड 3" से मेल खाता है; चूँकि यह अंतिम शब्द है जिसकी आप जाँच कर रहे हैं, यह आवश्यक नहीं है कि यह एक लुकहेड में हो, लेकिन इससे चोट न लगे।

एक पूरे पैराग्राफ से मिलान करने के लिए, आपको दोनों सिरों पर रेगेक्स को लंगर डालना होगा और .*शेष पात्रों का उपभोग करने के लिए एक अंतिम जोड़ना होगा । पर्ल-शैली संकेतन का उपयोग करना, जो होगा:

/^(?=.*word1)(?=.*word2)(?=.*word3).*$/m

'एम' संशोधक मल्टीलाइन मोड के लिए है; यह सुविधा देता है ^और $पैरा सीमाओं ( "लाइन सीमाओं" regex बात में) पर मैच। इस मामले में यह आवश्यक है कि आप 's' संशोधक का उपयोग करें, जो डॉट मेटाचैकर को नए वर्णनों के साथ-साथ सभी वर्णों से मेल खाता है।

अंत में, आप यह सुनिश्चित करना चाहते हैं कि आप पूरे शब्दों से मेल खा रहे हैं, न कि केवल लंबे शब्दों के टुकड़े, इसलिए आपको शब्द सीमाएँ जोड़ने की आवश्यकता है:

/^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b).*$/m

8
बिल्कुल सही - इस बारे में एक ट्यूटोरियल भी है! ocpsoft.org/tutorials/ अनियमित-expressions
लिंकन

9
बहुत बहुत धन्यवाद। * इससे फर्क पड़ता है
गेनाडी रियाबकिन

1
+1 स्पष्ट और रसीले उत्तर के लिए लुकहेड्स के लिए सबसे अच्छे उपयोगों में से एक का प्रदर्शन करता है (किसी पासवर्ड के प्रतिशत मिलान को गिनने के लिए हैक जैसे उपयोगों के विपरीत)। :)
zx81

1
@Liam :. MySQL POSIX ERE स्वाद का उपयोग करता है, इसलिए नहीं। यह प्रभावी रूप से प्रदर्शन के पक्ष में सुविधाओं का बलिदान करता है, जो मुझे उचित लगता है। यहाँ अधिक जानकारी है
एलन मूर

3
की जगह .*के साथ [\s\S]*जावास्क्रिप्ट में यदि आप के रूप में नई लाइनों है .जावास्क्रिप्ट का regex इंजन नई लाइनों से मेल नहीं खाता और न संशोधक के साथ बनाया जा सकता है
वेस्ले स्मिथ

41

इस उदाहरण को देखें:

हमारे पास 2 rexxps A और B हैं और हम उन दोनों का मिलान करना चाहते हैं, इसलिए छद्म कोड में यह इस तरह दिखता है:

pattern = "/A AND B/"

इसे इस तरह से और ऑपरेटर का उपयोग किए बिना लिखा जा सकता है:

pattern = "/NOT (NOT A OR NOT B)/"

पीसीआरई में:

"/(^(^A|^B))/"

regexp_match(pattern,data)

24
औपचारिक तर्क के संदर्भ में यह सच है, लेकिन यह बिल्कुल यहाँ कोई मदद नहीं है। Regexes में, AND की तुलना में व्यक्त करना और भी मुश्किल हो सकता है।
एलन मूर

@marvin_dpr यह मेरे लिए CMake में काम किया, जबकि अन्य सुझाव (?=expr)नहीं। यह कार्यान्वयन पर निर्भर प्रतीत होता है।
मेलेबियस

38
^रेगेक्स सिंटैक्स में "स्ट्रिंग की शुरुआत" का मतलब नहीं है?
लैम्ब्डा फेयरी

3
सामान्य तौर पर रेगेक्स में, ^केवल चरित्र वर्ग की शुरुआत में ही नकारात्मकता होती है। जब तक सीएमके वास्तव में कुछ नहीं कर रहे हैं (इस बिंदु पर जहां उनके पैटर्न मिलान भाषा "रेगेक्स" को कॉल करना भ्रामक या गलत माना जा सकता है) मैं इस तथ्य का अनुमान लगा रहा हूं कि यह आपके लिए एक अलग दुर्घटना थी।
ट्रिपल

29

आप एक नियमित अभिव्यक्ति के साथ ऐसा कर सकते हैं लेकिन शायद आप कुछ और चाहते हैं। उदाहरण के लिए कई regexp का उपयोग करें और उन्हें एक क्लॉज में संयोजित करें।

आप एक मानक regexp के साथ सभी संभव क्रमांकनों की गणना कर सकते हैं, इस तरह (किसी भी क्रम में a, b और c से मेल खाता है):

(abc)|(bca)|(acb)|(bac)|(cab)|(cba)

हालाँकि, यह बहुत लंबा और संभवतया अक्षम रीजेक्सप बना देता है, यदि आपके पास युगल शब्द से अधिक है।

यदि आप कुछ विस्तारित regexp संस्करण का उपयोग कर रहे हैं, जैसे पर्ल या जावा के, तो उनके पास ऐसा करने के बेहतर तरीके हैं। अन्य उत्तरों ने सकारात्मक रूपांतर संचालन का उपयोग करने का सुझाव दिया है।


10
मुझे नहीं लगता कि आपका दृष्टिकोण उनके भयावह बैकट्रैकिंग के साथ 3 लुकाहेड्स की तुलना में अधिक अक्षम है। यकीन है कि यह लिखना लंबा है, लेकिन ध्यान दें कि आप आसानी से अपने आप पैटर्न बना सकते हैं। ध्यान दें कि आप इसे जल्दी से विफल करने के लिए सुधार कर सकते हैं a(bc|cb)|b(ac|ca)|c(ab|ba)। और सबसे महत्वपूर्ण, आप इसे सभी रेगेक्स स्वाद के साथ उपयोग कर सकते हैं।
कासिमिर एट हिप्पोलाईट

26

AND ऑपरेटर RegExp सिंटैक्स में निहित है।
OR ऑपरेटर को इसके बजाय एक पाइप के साथ निर्दिष्ट किया जाना है।
निम्नलिखित RegExp:

var re = /ab/;

अक्षर a और अक्षर का मतलब है b
यह समूहों के साथ भी काम करता है:

var re = /(co)(de)/;

इसका मतलब समूह co और समूह है de
(और) के साथ और एक के साथ निम्नलिखित लाइनों की आवश्यकता होगी:

var re = /a|b/;
var re = /(co)|(de)/;

29
दुर्भाग्य से, यह वह नहीं है जो ओपी ने पूछा था। यह उस क्रम में कुछ भी पाता है, जबकि वे उन्हें किसी भी क्रम में चाहते थे। नीचे दिए गए जवाब में stackoverflow.com/users/20938/alan-moore द्वारा उत्तर देखें।
JESii

1
@JESii आपकी बात के लिए धन्यवाद, आप सही हैं और मैंने हुग्वारे से प्रश्न को गलत समझा, मैंने विशेष रूप से अपने पहले वाक्य पर ध्यान केंद्रित किया। सही जवाब लुकहेड ऑपरेटर का एक उचित उपयोग है, जैसा कि अलनमोर ने लिखा था। किसी भी तरह से मुझे लगता है कि किसी को मेरा स्पष्टीकरण उपयोगी हो सकता है, जैसा कि पहले ही उखाड़ दिया गया है, इसलिए मैं सब कुछ नहीं फेंकूंगा। सादर।
इमानुएल डेल ग्रैंडे

13

क्या आपके मामले में AND कई मिलान परिणामों पर करना संभव नहीं है? स्यूडोकोड में

regexp_match(pattern1, data) && regexp_match(pattern2, data) && ...

3
मैं ऐसी स्थिति में हूं जहां मेरे पास कुछ कोड है जो नियमों की एक डेटा तालिका है, नियम की वैधता का परीक्षण करने के लिए एकल रेगेक्स पैटर्न मैच स्ट्रिंग के साथ। कई परीक्षणों में जाना कुछ ऐसा नहीं है जो मैं अपने मामले में कर सकता हूं, और आमतौर पर अन्य लोगों के मामलों में भी!
एलन वोल्फ

11

क्यों नहीं awk का उपयोग करें?
जाग regex और के साथ, या मामलों इतना आसान है

awk '/WORD1/ && /WORD2/ && /WORD3/' myfile

9

यदि आप पर्ल रेगुलर एक्सप्रेशन का उपयोग करते हैं, तो आप पॉजिटिव लुकहेड का उपयोग कर सकते हैं:

उदाहरण के लिए

(?=[1-9][0-9]{2})[0-9]*[05]\b

संख्या 100 से अधिक होगी और 5 से विभाज्य होगी



8

स्वीकृत उत्तर के अतिरिक्त

मैं आपको कुछ व्यावहारिक उदाहरण प्रदान करूंगा, जो आप में से कुछ को स्पष्ट करेंगे। उदाहरण के लिए हम कहते हैं कि हमारे पास पाठ की तीन पंक्तियाँ हैं:

[12/Oct/2015:00:37:29 +0200] // only this + will get selected
[12/Oct/2015:00:37:x9 +0200]
[12/Oct/2015:00:37:29 +020x]

यहाँ डेमो देखें डेमो

हम यहां क्या करना चाहते हैं + चिन्ह का चयन करना है, लेकिन केवल अगर यह दो अंकों के बाद है और यदि यह चार संख्याओं से पहले है। वे ही अड़चन हैं। हम इसे प्राप्त करने के लिए इस नियमित अभिव्यक्ति का उपयोग करेंगे:

'~(?<=\d{2} )\+(?=\d{4})~g'

ध्यान दें कि यदि आप अभिव्यक्ति को अलग करते हैं तो यह आपको अलग परिणाम देगा।

या शायद आप टैग के बीच कुछ पाठ का चयन करना चाहते हैं ... लेकिन टैग नहीं! तब आप उपयोग कर सकते हैं:

'~(?<=<p>).*?(?=<\/p>)~g'

इस पाठ के लिए:

<p>Hello !</p> <p>I wont select tags! Only text with in</p> 

यहाँ डेमो देखें डेमो


कौन सा उत्तर स्वीकृत उत्तर था? कृपया मुझे भविष्य के लिए इसके लिए एक लिंक जोड़ें।
जेम्स ब्राउन

6

आदेश हमेशा नियमित अभिव्यक्ति की संरचना में निहित होता है। आप क्या चाहते हैं, इसे पूरा करने के लिए, आपको अलग-अलग अभिव्यक्तियों के खिलाफ कई बार इनपुट स्ट्रिंग से मिलान करना होगा।

आप जो करना चाहते हैं, वह एकल रेगेक्स के साथ संभव नहीं है।


यह तकनीकी रूप से असंभव नहीं है, लेकिन लागू करने के लिए सार्थक नहीं है। मुझे पता नहीं क्यों किसी ने नीचा दिखाया ...
रॉबर्ट पी

13
शायद इसलिए कि यह न केवल संभव है, यह सरल है, यह मानते हुए कि आपका रेगेक्स स्वाद लुकहेड का समर्थन करता है। और यह एक अच्छा दांव है; आज की अधिकांश प्रमुख प्रोग्रामिंग भाषाएं उनका समर्थन करती हैं।
एलन मूर

3

नियमित अभिव्यक्ति के बाहर और बाहर का उपयोग करें। PHP में लुकहेड ऑपरेटर मेरे लिए काम नहीं करता था, इसके बजाय मैंने इसका इस्तेमाल किया

if( preg_match("/^.{3,}$/",$pass1) && !preg_match("/\s{1}/",$pass1))
    return true;
else
    return false;

यदि पासवर्ड की लंबाई 3 वर्ण या अधिक है और उपरोक्त पासवर्ड में रिक्त स्थान नहीं है, तो उपरोक्त रेगेक्स मेल खाएगा।

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