रेगेक्स - एक विशेष पैटर्न को छोड़कर सब कुछ कैसे मेल खाता है


171

मैं किसी भी स्ट्रिंग से मेल खाने के लिए रेगेक्स कैसे लिखता हूं जो किसी विशेष पैटर्न से नहीं मिलता है? मैं एक ऐसी स्थिति से सामना कर रहा हूँ जहाँ मुझे एक (A और ~ B) पैटर्न से मेल खाना है।


PCRE इसके लिए सबसे अच्छा होगा: Regex पैटर्न्स को मैच के लिए देखें , जब ... को छोड़कर । मैंने findstrटैग हटा दिया क्योंकि यहाँ सभी उत्तर टैग के लिए मान्य नहीं हैं।
विकटोरिया स्ट्रीब्यू

जवाबों:


192

आप एक नज़र-से-आगे का उपयोग कर सकते हैं:

(?!999)\d{3}

यह उदाहरण इसके अलावा तीन अंकों से मेल खाता है 999


लेकिन अगर आपके पास इस सुविधा के साथ एक नियमित अभिव्यक्ति कार्यान्वयन नहीं है (देखें नियमित अभिव्यक्ति स्वादों की तुलना ), तो आपको संभवतः अपने दम पर बुनियादी सुविधाओं के साथ एक नियमित अभिव्यक्ति का निर्माण करना होगा।

केवल मूल वाक्यविन्यास के साथ एक संगत नियमित अभिव्यक्ति होगी:

[0-8]\d\d|\d[0-8]\d|\d\d[0-8]

यह किसी भी तीन अंकों के अनुक्रम से मेल खाता है जो नहीं है 999


1
देखो-आगे मानक नियमित अभिव्यक्ति वाक्यविन्यास नहीं है, यह एक पर्ल एक्सटेंशन है, यह केवल पर्ल, पीसीआरई (पर्ल-कम्पेटिबल रेगेक्स) या अन्य गैर-मानक कार्यान्वयनों में काम करेगा
जूलियानो

10
यह मानक नहीं हो सकता है, लेकिन अधिकांश आधुनिक भाषाएं इसका समर्थन नहीं करती हैं? इन दिनों कौन सी भाषा लुक-अहिदे का समर्थन नहीं करती है?
ब्रायन ओकले

1
यह सच है। लेकिन अधिकांश रेगेक्स फ्लेवर इस सुविधा का समर्थन करते हैं (देखें < regular-expressions.info/refflavors.html> )।
गुम्बो

1
मुझे लगता है कि पिछले regex भी 009, 019 ... आदि से मेल नहीं होगा
सेबस्टियन Viereck

1
C के लिए Standard Lex PCREs का उपयोग नहीं करता है :-(
pieman72

30

यदि आप एक स्ट्रिंग में एक शब्द से मेल खाना चाहते हैं और एक शब्द बी से मेल नहीं खाते हैं। उदाहरण के लिए: यदि आपके पास एक पाठ है:

1. I have a two pets - dog and a cat
2. I have a pet - dog

यदि आप पाठ की उन पंक्तियों की खोज करना चाहते हैं जो एक पालतू जानवर के लिए एक कुत्ता है और DOESN'T के पास बिल्ली नहीं है तो आप इस नियमित अभिव्यक्ति का उपयोग कर सकते हैं:

^(?=.*?\bdog\b)((?!cat).)*$

यह केवल दूसरी पंक्ति ढूंढेगा:

2. I have a pet - dog

वह प्रश्न में इसका उल्लेख करने में विफल रहा, लेकिन ओपी वास्तव में डॉस findstrकमांड का उपयोग कर रहा है । यह उन क्षमताओं का केवल एक छोटा सा उप-भाग देता है, जिन्हें आप रेगेक्स टूल में खोजने की अपेक्षा करते हैं; लुकहैड उनमें से नहीं है। (मैं सिर्फ खुद को खोजा टैग जोड़ा ।)
एलन मूर

2
हम्म, हाँ, मुझे अब पोस्टों पर उनकी एक टिप्पणी में मिला। मैंने शीर्षक में रेगेक्स को देखा। वैसे भी, अगर किसी को नियमित अभिव्यक्ति के लिए खोज करते समय यह पोस्ट मिलती है, जैसे मैंने किया, तो शायद यह किसी के लिए उपयोगी हो सकता है :) टिप्पणियों के लिए धन्यवाद
एलेक्सा

15

पैटर्न के खिलाफ मैच करें और मैच के बूलियन परिणाम को पलटने के लिए मेजबान भाषा का उपयोग करें। यह बहुत अधिक सुपाठ्य और बनाए रखने योग्य होगा।


1
फिर मैं सिर्फ (ए और ~ बी) के बजाय (~ ए या बी) के साथ समाप्त होता हूं। यह मेरी समस्या का समाधान नहीं है।
नोट नहीं

1
छद्म कोड: स्ट्रिंग टोटेस्ट; अगर (toTest.matches (A) और! toTest.matches (B)) {...}
बेन एस

मुझे अधिक स्पष्ट होना चाहिए था - टुकड़े पूरी तरह से स्वतंत्र नहीं हैं। यदि A स्ट्रिंग के भाग से मेल खाता है, तो हम परवाह करते हैं कि ~ B इसके बाकी हिस्सों से मेल खाता है (लेकिन जरूरी नहीं कि पूरी चीज)। यह विंडोज़ कमांड-लाइन फ़ॉरेस्ट फ़ंक्शन के लिए था, जो मैंने पाया कि यह वास्तविक रेगेक्स तक ही सीमित है, इसलिए मूट बिंदु।
notnot

8

ध्यान दें, इस प्राचीन प्रश्न को फिर से जीवित करना क्योंकि इसका एक सरल समाधान था जिसका उल्लेख नहीं किया गया था। ( रेगेक्स बाउंटी खोज के लिए कुछ शोध करते हुए आपका प्रश्न पाया गया ।)

मैं एक ऐसी स्थिति से सामना कर रहा हूँ जहाँ मुझे एक (A और ~ B) पैटर्न से मेल खाना है।

इस के लिए मूल regex भयावह सरल है: B|(A)

आप केवल समग्र मैचों को अनदेखा करते हैं और समूह 1 के कैप्चर की जांच करते हैं, जिसमें ए होगा।

एक उदाहरण (regex में html पार्स करने के बारे में सभी अस्वीकरणों के साथ): A अंक है, B अंक के भीतर है <a tag

रेगेक्स: <a.*?<\/a>|(\d+)

डेमो (निचले दाएं फलक में समूह 1 देखें)

संदर्भ

S1, s2, s3 की स्थितियों को छोड़कर पैटर्न से कैसे मिलान करें

जब तक एक पैटर्न का मिलान कैसे करें ...


यह सच होने के लिए बहुत अच्छा लगता है! दुर्भाग्य से, यह समाधान सार्वभौमिक नहीं है और यह Emacs में विफल रहता है, यहां तक ​​कि \dसाथ प्रतिस्थापित करने के बाद भी [[:digit:]]पहले संदर्भ में यह उल्लेख है कि यह पर्ल और पीएचपी के लिए विशिष्ट है: "पर्ल और पीएचपी के लिए सिंटैक्स विशिष्ट का उपयोग करके एक भिन्नता है जो समान है।"
मिगेलमोरिन

4

एक नियमित भाषा का पूरक भी एक नियमित भाषा है, लेकिन इसका निर्माण करने के लिए आपको नियमित भाषा के लिए DFA का निर्माण करना होगा , और किसी भी मान्य स्थिति को एक त्रुटि में बदलना होगा। इसे एक उदाहरण के लिए देखें । पेज क्या नहीं कहता है कि यह में बदल /(ac|bd)/गया है /(a[^c]?|b[^d]?|[^ab])/। एक DFA से नियमित अभिव्यक्ति में रूपांतरण तुच्छ नहीं है। यह आसान है अगर आप नियमित अभिव्यक्ति का अपरिवर्तित उपयोग कर सकते हैं और शब्दार्थ को कोड में बदल सकते हैं, जैसा कि पहले सुझाया गया है।


2
अगर मैं वास्तविक रेगेक्स के साथ काम कर रहा था तो यह सब लूट होगा। रेगेक्स अब पैटर्न से मेल खाते हुए अस्पष्ट CSG-ish (?) स्पेस का उल्लेख करता है जो कि ज्यादातर लैंगगेज समर्थन करते हैं। चूंकि मुझे मैच (A और ~ B) करने की आवश्यकता है, इसलिए नकारात्मकता को दूर करने का कोई तरीका नहीं है और फिर भी यह सब एक चरण में करना है।
नोट नहीं

जैसा कि ऊपर वर्णित किया गया है, लुकहेड ने ऐसा किया होता यदि खोज में डीएफए रेगेक्स से परे कुछ भी होता। यह पूरी तरह से अजीब है और मुझे नहीं पता कि मुझे यह कमांड-लाइन (अब बैच) शैली क्यों करनी है। यह मेरे हाथ बंधे रहने का एक और उदाहरण है।
नोट नहीं

1
@ नोट: आप विंडोज से मैट्रस्ट का उपयोग कर रहे हैं? फिर आपको बस वी / वी चाहिए। जैसे: findstr a inputfile | findstr / v B> outputfile.txt पहली पंक्ति ए के साथ सभी मेल खाती है, दूसरी उन सभी लाइनों से मेल खाती है जिनमें बी नहीं है
जूलियानो

धन्यवाद! यह वास्तव में मैं क्या जरूरत है। हालांकि, मैंने इस तरह से सवाल नहीं पूछा, इसलिए मैं अभी भी गुंबो को अधिक सामान्यीकृत उत्तर के लिए जवाब दे रहा हूं।
notnot

1

पैटर्न - पुनः

str.split(/re/g) 

पैटर्न को छोड़कर सब कुछ वापस आ जाएगा।

यहाँ परीक्षण करें


आप शायद यह उल्लेख करना चाहते हैं कि आपको फिर से शामिल होने की आवश्यकता है।
टोमडेमुइट

एक समान दृष्टिकोण का उपयोग कर रहा है replace str.replace(/re/g, ''), तो उन्हें फिर से शामिल करने की कोई आवश्यकता नहीं है। अगर तुम एक अच्छा अनुगामी \ 's में फेंक दो? जैसे str.replace(/\re\s?/g, '')तब आप किसी भी डुप्लिकेट स्थान से छुटकारा पा
लेते हैं

0

यहाँ मेरा जवाब आपकी समस्या को हल कर सकता है:

https://stackoverflow.com/a/27967674/543814

  • प्रतिस्थापन के बजाय, आप मिलान का उपयोग करेंगे।
  • समूह के बजाय $1, आप समूह पढ़ेंगे $2
  • समूह $2को वहां गैर-कैप्चरिंग बनाया गया था, जिसे आप टालेंगे।

उदाहरण:

Regex.Match("50% of 50% is 25%", "(\d+\%)|(.+?)");

पहला कैप्चरिंग समूह उस पैटर्न को निर्दिष्ट करता है जिससे आप बचना चाहते हैं। अंतिम कैप्चरिंग ग्रुप बाकी सब को पकड़ लेता है। सीधे शब्दों में, उस समूह को पढ़ा $2


0
(B)|(A)

तो क्या समूह 2 का उपयोग कब्जा ...


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