एक पंक्ति से मेल खाने के लिए नियमित अभिव्यक्ति जिसमें एक शब्द नहीं है


4292

मुझे पता है कि एक शब्द का मिलान करना संभव है और फिर अन्य उपकरणों (जैसे grep -v) का उपयोग करके मैचों को उल्टा करना है । हालाँकि, क्या ऐसी रेखाओं का मिलान करना संभव है जिनमें एक विशिष्ट शब्द नहीं है, उदाहरण के लिए hede, एक नियमित अभिव्यक्ति का उपयोग करते हुए?

इनपुट:

hoho
hihi
haha
hede

कोड:

grep "<Regex for 'doesn't contain hede'>" input

वांछित उत्पादन:

hoho
hihi
haha

84
शायद कुछ साल देर से, लेकिन इसमें क्या गलत है ([^h]*(h([^e]|$)|he([^d]|$)|hed([^e]|$)))*:? विचार सरल है। जब तक आप अवांछित स्ट्रिंग की शुरुआत नहीं देखते तब तक मिलान करते रहें, फिर केवल एन -1 मामलों में मिलान करें जहां स्ट्रिंग अधूरा है (जहां एन स्ट्रिंग की लंबाई है)। ये एन -1 मामले "गैर-ई के बाद एच", "उसके बाद गैर-डी", और "गैर-ई द्वारा पीछा किए जाने वाले" हैं। यदि आप इन एन -1 मामलों को पारित करने में कामयाब रहे, तो आप अवांछित स्ट्रिंग से सफलतापूर्वक मेल नहीं खाते, ताकि आप [^h]*फिर से तलाश शुरू कर सकें
stevendesu

323
@stevendesu: 'a-very-very-long-word' या इससे भी बेहतर आधे वाक्य के लिए इसे आज़माएँ। मस्ती टाइपिंग करो। BTW, यह लगभग अपठनीय है। प्रदर्शन प्रभाव के बारे में नहीं जानते।
पीटर शुएत्ज़े

13
@PeterSchuetze: निश्चित रूप से यह बहुत लंबे शब्दों के लिए सुंदर नहीं है, लेकिन यह एक व्यवहार्य और सही समाधान है। हालाँकि, मैंने प्रदर्शन पर परीक्षण नहीं चलाया है, मैं इसकी कल्पना भी धीमी नहीं करूंगा क्योंकि अधिकांश बाद के नियमों को अनदेखा किया जाता है जब तक कि आप एक एच (या शब्द, वाक्य, आदि का पहला अक्षर) नहीं देखते हैं। और आप पुनरावृत्त स्ट्रिंग को आसानी से पुनरावृत्ति स्ट्रिंग का उपयोग कर उत्पन्न कर सकते हैं। यदि यह काम करता है और जल्दी से उत्पन्न किया जा सकता है, तो क्या यह महत्वपूर्ण है? यह टिप्पणी किस लिए है
stevendesu

57
@stevendesu: मैं बाद में भी हूँ, लेकिन यह जवाब लगभग पूरी तरह से गलत है। एक बात के लिए, इस विषय को "h" सम्‍मिलित करना होगा, जो इसे नहीं करना चाहिए था, यह देखते हुए कि यह कार्य "मैच लाइन्स" है, जिसमें एक विशिष्ट शब्द नहीं है। आइए हम मान लें कि आप आंतरिक समूह को वैकल्पिक बनाने के लिए हैं, और यह कि पैटर्न ^([^h]*(h([^e]|$)|he([^d]|$)|hed([^e]|$))?)*$ एंकरिंग है : यह तब विफल हो जाता है जब "हैड" के उदाहरण "हेडेड" के आंशिक उदाहरणों से पहले होते हैं जैसे कि "हेडेड"।
jaytea

8
इस प्रश्न को "उन्नत रेगेक्स-फू" के तहत स्टैक ओवरफ्लो रेगुलर एक्सप्रेशन एफएक्यू में जोड़ा गया है ।
एलिटाल्मिंड

जवाबों:


5891

यह धारणा कि रेगेक्स उलटा मिलान का समर्थन नहीं करता है, पूरी तरह से सच नहीं है। आप नकारात्मक दिखावट का उपयोग करके इस व्यवहार की नकल कर सकते हैं:

^((?!hede).)*$

रेगुलर एक्सप्रेशन से ऊपर एक लाइन ब्रेक के बिना किसी भी स्ट्रिंग, या लाइन से मिलान करेगा, नहीं (उप) स्ट्रिंग 'Hede' वाले। जैसा कि बताया जा यह कुछ regex में "अच्छा" है (या करना चाहिए) नहीं है, लेकिन फिर भी, यह है संभव।

और अगर आपको लाइन ब्रेक चार्ट से भी मेल खाना है, तो DOT-ALL संशोधक ( sनिम्नलिखित पैटर्न में अनुगामी ) का उपयोग करें:

/^((?!hede).)*$/s

या इनलाइन का उपयोग करें:

/(?s)^((?!hede).)*$/

(जहां /.../रेगेक्स सीमांकक हैं, यानी पैटर्न का हिस्सा नहीं)

यदि DOT-ALL संशोधक उपलब्ध नहीं है, तो आप वर्ण वर्ग के साथ समान व्यवहार की नकल कर सकते हैं [\s\S]:

/^((?!hede)[\s\S])*$/

व्याख्या

एक स्ट्रिंग सिर्फ nपात्रों की एक सूची है । प्रत्येक वर्ण के पहले और बाद में, एक खाली स्ट्रिंग है। तो nपात्रों की एक सूची में n+1खाली तार होंगे। स्ट्रिंग पर विचार करें "ABhedeCD":

    ┌──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┐
S = e1 A e2 B e3 h e4 e e5 d e6 e e7 C e8 D e9
    └──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┘

index    0      1      2      3      4      5      6      7

जहां eखाली तार हैं। रेगेक्स (?!hede).देखने के लिए आगे देखता है कि क्या कोई विकल्प नहीं "hede"है, और यदि ऐसा है (तो कुछ और देखा जाता है), तो .(डॉट) एक लाइन ब्रेक को छोड़कर किसी भी चरित्र से मेल खाएगा। लुक-अराउंड को शून्य-चौड़ाई-अभिकथन भी कहा जाता है क्योंकि वे किसी भी वर्ण का उपभोग नहीं करते हैं । वे केवल कुछ का दावा / सत्यापन करते हैं।

इसलिए, मेरे उदाहरण में, प्रत्येक खाली स्ट्रिंग को पहले यह देखने के लिए मान्य किया जाता है कि क्या कोई "hede"आगे नहीं है, इससे पहले कि एक चरित्र .(डॉट) द्वारा खपत होती है । रेगेक्स (?!hede).ऐसा केवल एक बार करेगा, इसलिए इसे एक समूह में लपेटा जाता है, और शून्य या अधिक बार दोहराया जाता है ((?!hede).)*:। अंत में, पूरे इनपुट का उपभोग करने के लिए स्टार्ट-एंड-एंड-इनपुट का उपयोग किया जाता है:^((?!hede).)*$

आप देख सकते हैं, इनपुट "ABhedeCD"क्योंकि पर विफल हो जाएगा e3, regex (?!hede)विफल रहता है (वहाँ है "hede" आगे!)।


26
मैं यह कहने के लिए इतनी दूर नहीं जाऊंगा कि यह ऐसा कुछ है जो रेगेक्स पर बुरा है। इस समाधान की सुविधा बहुत स्पष्ट है और एक प्रोग्रामेटिक खोज की तुलना में प्रदर्शन हिट अक्सर महत्वहीन होने वाला है।
आर्किमारेड्स

29
सख्ती से नकारात्मक लुक-अप बोलते हुए आप नियमित अभिव्यक्ति को नियमित नहीं बनाते हैं।
K पर पीटर के

55
@PeterK, निश्चित, लेकिन यह SO है, ना कि MathOverflow या CS-Stackexchange। यहां सवाल पूछने वाले लोग आमतौर पर व्यावहारिक उत्तर की तलाश में रहते हैं। अधिकांश पुस्तकालय या उपकरण (जैसे grep, जो ओपी का उल्लेख करते हैं) regex- समर्थन के साथ सभी में ऐसी विशेषताएं हैं जो उन्हें सैद्धांतिक रूप से गैर-नियमित रूप से प्रभावित करती हैं।
बार्ट कीर्स

19
@ बर्ट कियर्स, आप के लिए कोई अपराध नहीं है, बस शब्दावली का यह दुरुपयोग मुझे थोड़ा परेशान करता है। यहां वास्तव में भ्रमित करने वाला हिस्सा यह है कि सख्त अर्थों में नियमित अभिव्यक्तियाँ बहुत कुछ कर सकती हैं, जो ओपी चाहता है, लेकिन उन्हें लिखने के लिए आम भाषा इसकी अनुमति नहीं देती है, जो लुक-अहिदे की तरह (गणितीय रूप से बदसूरत) कामचोर की ओर जाता है। कृपया इस उत्तर को नीचे देखें और मेरी टिप्पणी वहाँ (सैद्धांतिक रूप से संरेखित) करने के उचित तरीके के लिए। कहने की जरूरत नहीं है कि यह बड़े इनपुट पर तेजी से काम करता है।
पीटर के

17
मामले में आपने कभी सोचा है कि यह कैसे करना है:^\(\(hede\)\@!.\)*$
बाल्डर्स

738

ध्यान दें कि समाधान "हैड" से शुरू नहीं होता है :

^(?!hede).*$

आम तौर पर समाधान से बहुत अधिक कुशल होता है जिसमें "हैड" नहीं होता है :

^((?!hede).)*$

इनपुट स्ट्रिंग के पहले स्थान पर केवल "हैड" के लिए पूर्व चेक, बल्कि प्रत्येक स्थिति पर।


5
धन्यवाद, मैं इसका इस्तेमाल किया मान्य करने के लिए है कि स्ट्रिंग dosn't अंक ^ ((\ घ {5,})?!।) * के squence शामिल
Samih एक

2
नमस्कार! मैं रचना नहीं कर सकता "हेज" रेगेक्स के साथ समाप्त नहीं होता है । क्या आप इसके साथ मदद कर सकते हैं?
Aleks हां

1
@AleksYa: बस "समाहित करें" संस्करण का उपयोग करें, और अंतिम स्ट्रिंग को खोज स्ट्रिंग में शामिल करें: "हेज" से "हेज $" में "मेल नहीं" करने के लिए स्ट्रिंग को बदलें
Nyerguds

2
@AleksYa: वर्जन एंड नेगेटिव लुकबाइंड के रूप में प्रयोग नहीं किया जा सकता है (.*)(?<!hede)$:। @Nyerguds 'संस्करण भी काम करेगा, लेकिन उत्तर के उल्लेख पर प्रदर्शन को पूरी तरह से याद करता है।
thisismydesign

5
इतने जवाब क्यों कह रहे हैं ^((?!hede).)*$? क्या यह उपयोग करने के लिए अधिक कुशल नहीं है ^(?!.*hede).*$? यह वही काम करता है लेकिन कुछ ही चरणों में
जैकप्रैड

208

यदि आप इसे केवल grep के लिए उपयोग कर रहे हैं, तो आप उन grep -v hedeसभी लाइनों को प्राप्त करने के लिए उपयोग कर सकते हैं जिनमें हेज नहीं है।

ईटीए ओह, इस प्रश्न को फिर से जोड़ते हुए, grep -vसंभवतः "उपकरण विकल्प" से आपका क्या अभिप्राय है।


22
युक्ति: उत्तरोत्तर फ़िल्टरिंग के लिए जो आप नहीं चाहते हैं: grep -v "hede" | grep -v "hihi" | ...आदि।
ओलिवियर लालोंडे

51
या केवल एक प्रक्रिया का उपयोग करनाgrep -v -e hede -e hihi -e ...
ओलाफ डाइटचेस

15
या सिर्फ grep -v "hede\|hihi":)
पुटनिक

2
यदि आपके पास कई पैटर्न हैं, जिन्हें आप फ़िल्टर करना चाहते हैं, तो उन्हें एक फ़ाइल में grep -vf pattern_file file
डालें

4
या बस egrepया grep -Ev "hede|hihi|etc"अजीब भागने से बचने के लिए।
अमित नायडू

159

उत्तर:

^((?!hede).)*$

स्पष्टीकरण:

^स्ट्रिंग की शुरुआत, (समूह और कैप्चर to \ 1 (0 या अधिक बार (संभव सबसे अधिक मिलान)),
(?!आगे देखने के लिए देखें कि क्या नहीं है,

hede आपका तार,

)लुक-फॉरवर्ड का अंत ., \ n को छोड़कर , किसी भी वर्ण का
)*अंत \ _ (नोट: क्योंकि आप इस कैप्चर पर एक क्वांटिफायर का उपयोग कर रहे हैं, केवल कैप्चर किए गए पैटर्न का केवल दोहराव
$वैकल्पिक \ n से पहले \ 1 में संग्रहीत किया जाएगा) , और स्ट्रिंग का अंत


14
भयानक कि उदात्त पाठ 2 में मेरे लिए काम किया कई शब्दों 'का उपयोग ^((?!DSAU_PW8882WEB2|DSAU_PW8884WEB2|DSAU_PW8884WEB).)*$'
दामोदर Bashyal

3
@DamodarBashyal मुझे पता है कि मैं यहाँ बहुत देर से पहुँच रहा हूँ, लेकिन आप पूरी तरह से वहाँ दूसरा शब्द निकाल सकते हैं और आपको ठीक उसी परिणाम
मिलेंगे

99

दिए गए उत्तर पूरी तरह से ठीक हैं, बस एक शैक्षणिक बिंदु:

सैद्धांतिक कंप्यूटर विज्ञान के अर्थ में नियमित अभिव्यक्तियाँ इस तरह से नहीं होतीं । उनके लिए यह कुछ इस तरह देखना था:

^([^h].*$)|(h([^e].*$|$))|(he([^h].*$|$))|(heh([^e].*$|$))|(hehe.+$) 

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


1
यह ध्यान रखना महत्वपूर्ण है कि केवल बेसिक POSIX.2 नियमित अभिव्यक्ति का उपयोग करता है और इस प्रकार जब पीसीआर उपलब्ध नहीं है, तब तक अधिक पोर्टेबल है।
स्टीव-ओ

5
मैं सहमत हूँ। बहुत से नियमित अभिव्यक्ति नहीं होने पर कई लोग नियमित भाषा नहीं हैं और एक परिमित ऑटोमेटा द्वारा मान्यता प्राप्त नहीं हो सकते हैं।
थॉमसमैक्लोड

@ThomasMcLeod, Hades32: क्या यह किसी भी संभव नियमित भाषा के दायरे में है जो ' नहीं ' और ' और ' के साथ-साथ 'जैसे' या 'अभिव्यक्ति' के (hede|Hihi)'' कहने में सक्षम है ? (यह शायद सीएस के लिए एक सवाल है।)
जेम्स हाई

7
@ जॉनन: मुझे !!! ... खैर, वास्तविक रेगेक्स नहीं, बल्कि अकादमिक संदर्भ, जो कम्प्यूटेशनल जटिलता से भी निकटता से संबंधित है; PCREs मौलिक रूप से POSIX नियमित अभिव्यक्तियों के समान दक्षता की गारंटी नहीं दे सकते।
जेम्स हाई

4
क्षमा करें, इसका उत्तर सिर्फ काम नहीं करता है, यह ह्हे से मेल खाएगा और यहां तक ​​कि आंशिक रूप से (दूसरी छमाही) से मेल खाएगा
फाल्को

60

यदि आप चाहते हैं कि रेगेक्स टेस्ट केवल विफल हो जाए यदि पूरे स्ट्रिंग से मेल खाता है, तो निम्नलिखित काम करेगा:

^(?!hede$).*

उदाहरण - यदि आप "फू" (यानी "फूफो", "बारफू", और "फोब्बर" को छोड़कर सभी मूल्यों को अनुमति देना चाहते हैं, लेकिन "फू" विफल हो जाएगा), का उपयोग करें: ^(?!foo$).*

बेशक, यदि आप सटीक समानता के लिए जाँच कर रहे हैं, तो इस मामले में एक बेहतर सामान्य समाधान स्ट्रिंग समानता, यानी की जाँच करना है

myStr !== 'foo'

यदि आप किसी भी regex सुविधाओं (यहाँ, मामला असंवेदनशीलता और सीमा मिलान) की आवश्यकता है, तो आप परीक्षण के बाहर नकार भी डाल सकते हैं :

!/^[a-f]oo$/i.test(myStr)

इस उत्तर के शीर्ष पर रेगेक्स समाधान सहायक हो सकता है, हालांकि, उन स्थितियों में जहां एक सकारात्मक रेगेक्स परीक्षण की आवश्यकता होती है (शायद एक एपीआई द्वारा)।


व्हाट्सएप का पता लगाने के बारे में क्या? उदाहरण के लिए, अगर मैं स्ट्रिंग के साथ असफल होना चाहता हूं " hede "?
ईगोर

@eagor का \sनिर्देशन एक ही व्हाट्सएप पात्र से मेल खाता है
रॉय टिंकर

धन्यवाद, लेकिन मैंने इस काम को करने के लिए regex को अपडेट करने का प्रबंधन नहीं किया।
ईगोर

2
@eagor:^(?!\s*hede\s*$).*
रॉय टिंकर

52

एफडब्ल्यूआईडब्ल्यू, चूंकि नियमित भाषाओं (उर्फ तर्कसंगत भाषाओं) को पूरकता के तहत बंद कर दिया गया है, इसलिए एक नियमित अभिव्यक्ति (उर्फ तर्कसंगत अभिव्यक्ति) को खोजने के लिए हमेशा संभव है जो एक और अभिव्यक्ति को नकारती है। लेकिन कई उपकरण इसे लागू नहीं करते हैं।

Vcsn इस ऑपरेटर का समर्थन करता है (जो इसे दर्शाता है {c}, पोस्टफ़िक्स )।

पत्र (लेबल कर रहे हैं: आप पहली बार अपने भाव के प्रकार को परिभाषित lal_charसे) लेने के लिए aकरने के लिए z(जब पूरक के साथ काम वर्णमाला को परिभाषित किया जाता है, ज़ाहिर है, बहुत महत्वपूर्ण) उदाहरण के लिए, और "मूल्य" प्रत्येक शब्द के लिए गणना की सिर्फ एक बूलियन है : trueशब्द को स्वीकार किया जाता है false, अस्वीकार कर दिया जाता है।

पायथन में:

In [5]: import vcsn
        c = vcsn.context('lal_char(a-z), b')
        c
Out[5]: {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}  𝔹

तब आप अपनी अभिव्यक्ति दर्ज करते हैं:

In [6]: e = c.expression('(hede){c}'); e
Out[6]: (hede)^c

इस अभिव्यक्ति को एक ऑटोमेटन में बदलें:

In [7]: a = e.automaton(); a

इसी ऑटोमोटिव

अंत में, इस ऑटोमेटन को एक साधारण अभिव्यक्ति में परिवर्तित करें।

In [8]: print(a.expression())
        \e+h(\e+e(\e+d))+([^h]+h([^e]+e([^d]+d([^e]+e[^]))))[^]*

जहां +आमतौर पर निरूपित किया जाता है |, \eखाली शब्द को दर्शाता है, और [^]आमतौर पर लिखा जाता है .(कोई भी चरित्र)। तो, थोड़ा फिर से लिखना ()|h(ed?)?|([^h]|h([^e]|e([^d]|d([^e]|e.)))).*

आप इस उदाहरण को यहाँ देख सकते हैं , और Vcsn को ऑनलाइन आज़मा सकते हैं


6
सच है, लेकिन बदसूरत, और केवल छोटे चरित्र सेट के लिए उल्लेखनीय है। आप यूनिकोड के तार के साथ ऐसा नहीं करना चाहते हैं :-)
reinierpost

अधिक उपकरण हैं जो इसे अनुमति देते हैं, सबसे प्रभावशाली रगेल में से एक । वहाँ यह (किसी भी * - ('हेहे' किसी भी *)) के रूप में शुरू-गठबंधन मैच या (किसी भी * - (हेहे 'किसी भी *)) के लिए लिखा जाएगा।
पीटर के

1
@reinierpost: यह बदसूरत क्यों है और यूनिकोड के साथ समस्या क्या है? मैं दोनों पर सहमत नहीं हो सकता। (मेरे पास vcsn के साथ कोई अनुभव नहीं है, लेकिन DFA के साथ है)।
पीटर के

3
@PedroGimeno जब आपने लंगर डाला, तो आपने इस रेगेक्स को पहले परेंस में रखना सुनिश्चित किया? अन्यथा एंकरों के बीच की मिसालें और |अच्छी तरह से नहीं खेलेंगे। '^(()|h(ed?)?|([^h]|h([^e]|e([^d]|d([^e]|e.)))).*)$'
akim

1
मुझे लगता है कि यह टिप्पणी करने योग्य है कि यह विधि उन रेखाओं के मेल के लिए है जो 'हेज' शब्द नहीं हैं , बल्कि उन पंक्तियों की तुलना में जिनमें 'हैड' शब्द नहीं है , जो कि ओपी ने पूछा है। उत्तरार्द्ध के लिए मेरा जवाब देखें।
पेड्रो जिमनो

51

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


10
कुछ उपकरण, और विशेष रूप से mysqldumpslow, केवल डेटा को फ़िल्टर करने के लिए इस तरह की पेशकश करते हैं, इसलिए ऐसे मामले में, ऐसा करने के लिए एक regex ढूंढना उपकरण को फिर से लिखने के अलावा सबसे अच्छा समाधान है। इसके लिए विभिन्न पैच 1 मिमी AB / Sun द्वारा शामिल नहीं किए गए हैं / ओरेकल।
एफजीएम

1
बिल्कुल मेरी स्थिति के लिए विनम्र। वेलोसिटी टेम्प्लेट इंजन एक ट्रांसफ़ॉर्मेशन (एस्केप html) को लागू करने के लिए तय करने के लिए नियमित अभिव्यक्तियों का उपयोग करता है और मैं चाहता हूं कि यह हमेशा एक स्थिति में EXCEPT काम करे।
हेन्नो वर्म्यूलेन

1
क्या विकल्प है? Ive को कभी भी ऐसी किसी चीज़ का सामना नहीं करना पड़ा जो रेगेक्स के अलावा सटीक स्ट्रिंग मिलान कर सके। यदि ओपी एक प्रोग्रामिंग भाषा का उपयोग कर रहा है, तो अन्य उपकरण भी उपलब्ध हो सकते हैं, लेकिन यदि वह कोड नहीं लिख रहा है, तो शायद कोई अन्य विकल्प नहीं है।
किंगफ्रिटो_5005

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

48

नकारात्मक रूपांतर के साथ, नियमित अभिव्यक्ति कुछ मैच कर सकती है जिसमें विशिष्ट पैटर्न नहीं होता है। इसका उत्तर और विवरण बार्ट कीर्स द्वारा दिया गया है। महान व्याख्या!

हालांकि, बार्ट कीर्स के जवाब के साथ, लुकहेड भाग किसी भी एकल चरित्र का मिलान करते हुए 1 से 4 वर्णों का परीक्षण करेगा। हम इससे बच सकते हैं और लुकहेड भाग को पूरे पाठ की जांच करने दे सकते हैं, सुनिश्चित करें कि कोई 'हैड' न हो, और फिर सामान्य भाग (*।) पूरे पाठ को एक समय में खा सकता है।

यहाँ सुधार रेगेक्स है:

/^(?!.*?hede).*$/

नोट करें * (*?) ऋणात्मक मात्रा में ऋणात्मक रूपांतर भाग में वैकल्पिक है, आप अपने डेटा के आधार पर इसके बजाय (*) लालची मात्रा का उपयोग कर सकते हैं: यदि 'हैड' मौजूद है और पाठ की शुरुआत में, आलसी क्वांटिफायर कर सकता है तेज होना; अन्यथा, लालची क्वांटिफायर तेज हो सकता है। हालाँकि अगर 'हैडेड' मौजूद नहीं है, तो दोनों समान होंगे।

यहाँ डेमो कोड है

लुकहेड के बारे में अधिक जानकारी के लिए, कृपया महान लेख देखें: लुकहैड और लुकहाइब

इसके अलावा, कृपया RegexGen.js , एक जावास्क्रिप्ट रेगुलर एक्सप्रेशन जेनरेटर देखें जो जटिल नियमित अभिव्यक्तियों के निर्माण में मदद करता है। RegexGen.js के साथ, आप regex को अधिक पठनीय तरीके से बना सकते हैं:

var _ = regexGen;

var regex = _(
    _.startOfLine(),             
    _.anything().notContains(       // match anything that not contains:
        _.anything().lazy(), 'hede' //   zero or more chars that followed by 'hede',
                                    //   i.e., anything contains 'hede'
    ), 
    _.endOfLine()
);

3
तो बस यह जांचने के लिए कि क्या दिए गए तार में str1 और str2 नहीं है:^(?!.*(str1|str2)).*$
S.Serpooshan

1
हां, या आप ^(?!.*?(?:str1|str2)).*$अपने डेटा के आधार पर आलसी क्वांटिफायर का उपयोग कर सकते हैं । जोड़ा गया ?:क्योंकि हमें इसे पकड़ने की आवश्यकता नहीं है।
एमोबिज़

यह 10xms के कारक द्वारा अब तक का सबसे अच्छा उत्तर है। यदि आपने अपना jsfiddle कोड जोड़ा है और उत्तर पर परिणाम लोग इसे नोटिस कर सकते हैं। मुझे आश्चर्य है कि जब आलसी नहीं होता है तो आलसी संस्करण लालची संस्करण की तुलना में तेज क्यों होता है। क्या उन्हें उतना समय नहीं लेना चाहिए?
user5389726598465

हां, वे उतना ही समय लेते हैं क्योंकि वे दोनों पूरे पाठ का परीक्षण करते हैं।
एमोबिज

41

मानक

मैंने प्रस्तुत कुछ विकल्पों का मूल्यांकन करने और उनके प्रदर्शन की तुलना करने के साथ-साथ कुछ नई विशेषताओं का उपयोग करने का निर्णय लिया। .NET रेगेक्स इंजन पर बेंचमार्किंग: http://regexhero.net/tester/

बेंचमार्क पाठ:

पहली 7 पंक्तियों का मिलान नहीं होना चाहिए, क्योंकि उनमें खोज की गई अभिव्यक्ति शामिल है, जबकि निचली 7 पंक्तियों का मिलान होना चाहिए!

Regex Hero is a real-time online Silverlight Regular Expression Tester.
XRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex HeroRegex HeroRegex HeroRegex HeroRegex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her Regex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.Regex Hero
egex Hero egex Hero egex Hero egex Hero egex Hero egex Hero Regex Hero is a real-time online Silverlight Regular Expression Tester.
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRegex Hero is a real-time online Silverlight Regular Expression Tester.

Regex Her
egex Hero
egex Hero is a real-time online Silverlight Regular Expression Tester.
Regex Her is a real-time online Silverlight Regular Expression Tester.
Regex Her Regex Her Regex Her Regex Her Regex Her Regex Her is a real-time online Silverlight Regular Expression Tester.
Nobody is a real-time online Silverlight Regular Expression Tester.
Regex Her o egex Hero Regex  Hero Reg ex Hero is a real-time online Silverlight Regular Expression Tester.

परिणाम:

परिणाम 3 रन के औसत के रूप में प्रति सेकंड Iterations हैं - बड़ा नंबर = बेहतर

01: ^((?!Regex Hero).)*$                    3.914   // Accepted Answer
02: ^(?:(?!Regex Hero).)*$                  5.034   // With Non-Capturing group
03: ^(?>[^R]+|R(?!egex Hero))*$             6.137   // Lookahead only on the right first letter
04: ^(?>(?:.*?Regex Hero)?)^.*$             7.426   // Match the word and check if you're still at linestart
05: ^(?(?=.*?Regex Hero)(?#fail)|.*)$       7.371   // Logic Branch: Find Regex Hero? match nothing, else anything

P1: ^(?(?=.*?Regex Hero)(*FAIL)|(*ACCEPT))  ?????   // Logic Branch in Perl - Quick FAIL
P2: .*?Regex Hero(*COMMIT)(*FAIL)|(*ACCEPT) ?????   // Direct COMMIT & FAIL in Perl

चूंकि .NET क्रिया क्रियाओं का समर्थन नहीं करता है (* विफल, आदि) मैं समाधान P1 और P2 का परीक्षण नहीं कर सका।

सारांश:

मैंने अधिकांश प्रस्तावित समाधानों का परीक्षण करने की कोशिश की, कुछ शब्दों के लिए कुछ अनुकूलन संभव हैं। उदाहरण के लिए यदि खोज स्ट्रिंग के पहले दो अक्षर समान नहीं हैं, तो उत्तर 03 को ^(?>[^R]+|R+(?!egex Hero))*$छोटे प्रदर्शन लाभ के परिणामस्वरूप विस्तारित किया जा सकता है ।

लेकिन समग्र रूप से सबसे पठनीय और प्रदर्शन-वार सबसे तेज समाधान सशर्त कथन का उपयोग करते हुए 05 या लगता है कि अधिनायक मात्रा के साथ 04 है। मुझे लगता है कि पर्ल का समाधान और भी तेज और आसानी से पढ़ने योग्य होना चाहिए।


5
आपको समय ^(?!.*hede)भी चाहिए । /// इसके अलावा, मिलान कॉर्पस और गैर-मिलान कॉर्पस के लिए अभिव्यक्तियों को अलग-अलग रैंक करना शायद बेहतर है क्योंकि यह आमतौर पर एक ऐसा मामला है जो अधिकांश लाइन मैच या अधिकांश लाइनें नहीं करता है।
इकेगामी

32

रेगेक्स नहीं, लेकिन मैंने शोर को खत्म करने के लिए पाइप के साथ सीरियल ग्रीप्स का उपयोग करना तर्कसंगत और उपयोगी पाया है।

जैसे। सभी टिप्पणियों के बिना एक अपाचे विन्यास फाइल खोजें

grep -v '\#' /opt/lampp/etc/httpd.conf      # this gives all the non-comment lines

तथा

grep -v '\#' /opt/lampp/etc/httpd.conf |  grep -i dir

धारावाहिक grep's (कोई टिप्पणी नहीं) का तर्क और (मिलान)


2
मुझे लगता है कि वह grep -v
रेगीज़

9
यह खतरनाक है। इसके अलावा लाइनों की याद आती है जैसेgood_stuff #comment_stuff
Xavi Montero

29

इसके साथ, आप प्रत्येक स्थिति पर एक लुकहेड का परीक्षण करने से बचते हैं:

/^(?:[^h]+|h++(?!ede))*+$/

के बराबर (for .net):

^(?>(?:[^h]+|h+(?!ede))*)$

पुराना उत्तर:

/^(?>[^h]+|h+(?!ede))*$/

7
अच्छी बात; मुझे आश्चर्य है कि किसी ने भी इस दृष्टिकोण का उल्लेख नहीं किया है। हालांकि, उस विशेष रेगेक्स को जब पाठ से मेल नहीं खाया जाता है, तो यह विनाशकारी बैकट्रैकिंग के लिए प्रवण होता है। यहां बताया गया है कि मैं यह कैसे करूंगा:/^[^h]*(?:h+(?!ede)[^h]*)*$/
एलन मूर

... या आप केवल सभी क्वांटिफायर को अपना अधिकार बना सकते हैं। ;)
एलन मूर

@ एलन मूर - मैं भी हैरान हूं। मैंने नीचे दिए गए उत्तर में इसी पैटर्न को पोस्ट करने के बाद ही आपकी टिप्पणी (और ढेर में सर्वश्रेष्ठ रेक्स) देखी।
राइडरुनर

@ridgerunner, सबसे अच्छा थियो होना जरूरी नहीं है। मैंने ऐसे बेंचमार्क देखे हैं जहां शीर्ष उत्तर बेहतर प्रदर्शन करता है। (मैं उस थो के बारे में हैरान था।)
क्यूटीएक्स

23

पूर्वोक्त (?:(?!hede).)*महान है क्योंकि यह लंगर डाला जा सकता है।

^(?:(?!hede).)*$               # A line without hede

foo(?:(?!hede).)*bar           # foo followed by bar, without hede between them

लेकिन इस मामले में निम्नलिखित पर्याप्त होगा:

^(?!.*hede)                    # A line without hede

इस सरलीकरण में "और" खंड जोड़ा गया है:

^(?!.*hede)(?=.*foo)(?=.*bar)   # A line with foo and bar, but without hede
^(?!.*hede)(?=.*foo).*bar       # Same

20

यहाँ है कि मैं यह कैसे करूँगा:

^[^h]*(h(?!ede)[^h]*)*$

अन्य उत्तरों की तुलना में सटीक और अधिक कुशल। यह फ्राइडल के "अनरोलिंग-द-लूप" दक्षता तकनीक को लागू करता है और बहुत कम बैकट्रैकिंग की आवश्यकता होती है।


17

यदि आप चरित्र को नकारने के लिए एक शब्द का मिलान नकारात्मक वर्ग के समान करना चाहते हैं:

उदाहरण के लिए, एक स्ट्रिंग:

<?
$str="aaa        bbb4      aaa     bbb7";
?>

प्रयोग नहीं करें:

<?
preg_match('/aaa[^bbb]+?bbb7/s', $str, $matches);
?>

उपयोग:

<?
preg_match('/aaa(?:(?!bbb).)+?bbb7/s', $str, $matches);
?>

सूचना "(?!bbb)."न तो देखने योग्य है और न ही देखने योग्य, यह उदाहरण के लिए, समान है:

"(?=abc)abcde", "(?!abc)abcde"

3
पर्ल रीगेक्सप में कोई "लुकट्रैक" नहीं है। यह वास्तव में एक नकारात्मक रूपांतर (उपसर्ग (?!) है। पॉजिटिव लुकहैड का उपसर्ग होगा, (?=जबकि संबंधित लुकहैंड उपसर्ग क्रमशः (?<!और (?<=क्रमशः होगा। लुकहैड का अर्थ है कि आप अगले पात्रों (इसलिए "आगे") को बिना उनका उपभोग किए पढ़ते हैं। एक लुकबाइंड का मतलब है कि आप उन पात्रों की जांच करते हैं जो पहले ही भस्म हो चुके हैं।
दिदियर एल

14

मेरे जवाबों में एक, शीर्ष उत्तर के अधिक पठनीय संस्करण:

^(?!.*hede)

मूल रूप से, "लाइन की शुरुआत में मेल खाता है यदि और केवल अगर इसमें 'हैडेड' नहीं है" - तो आवश्यकता लगभग रेगेक्स में सीधे अनुवाद की जाती है।

बेशक, कई विफलता आवश्यकताओं के लिए संभव है:

^(?!.*(hede|hodo|hada))

विवरण: ^ एंकर सुनिश्चित करता है कि रेगेक्स इंजन स्ट्रिंग में हर स्थान पर मैच को दोबारा न ले, जो हर स्ट्रिंग से मेल खाएगा।

^ शुरुआत में लंगर लाइन की शुरुआत का प्रतिनिधित्व करने के लिए है। Grep टूल एक बार में प्रत्येक पंक्ति से मेल खाता है, ऐसे संदर्भों में जहां आप एक बहु स्ट्रिंग के साथ काम कर रहे हैं, आप "m" ध्वज का उपयोग कर सकते हैं:

/^(?!.*hede)/m # JavaScript syntax

या

(?m)^(?!.*hede) # Inline flag

कई नकार के साथ उत्कृष्ट उदाहरण।
पीटर परादा

शीर्ष उत्तर से एक अंतर यह है कि यह कुछ भी मेल नहीं खाता है, और यह पूरी लाइन से मेल खाता है यदि "हैड" के बिना
Z. खुल्लाह

13

ओपी ने Tagसंदर्भ को इंगित करने के लिए या पोस्ट को निर्दिष्ट नहीं किया था (प्रोग्रामिंग भाषा, संपादक, उपकरण) रेगेक्स का उपयोग किया जाएगा।

मेरे लिए, मुझे कभी-कभी किसी फ़ाइल का उपयोग करते हुए संपादन करने की आवश्यकता होती है Textpad

Textpad कुछ रेगेक्स का समर्थन करता है, लेकिन लुकहेड या लुकबाइंड का समर्थन नहीं करता है, इसलिए यह कुछ कदम उठाता है।

अगर मैं उन सभी लाइनों को बनाए रखना चाह रहा हूं जिनमें स्ट्रिंग नहीं है hede, तो मैं इसे इस तरह से करूंगा:

1. किसी भी पाठ वाले प्रत्येक पंक्ति की शुरुआत में एक अद्वितीय "टैग" जोड़ने के लिए संपूर्ण फ़ाइल खोजें / बदलें।

    Search string:^(.)  
    Replace string:<@#-unique-#@>\1  
    Replace-all  

2. सभी पंक्तियों को हटा दें जिसमें स्ट्रिंग है hede(प्रतिस्थापन स्ट्रिंग खाली है):

    Search string:<@#-unique-#@>.*hede.*\n  
    Replace string:<nothing>  
    Replace-all  

3. इस बिंदु पर, शेष सभी पंक्तियों में स्ट्रिंग नहीं है hede। सभी लाइनों से अद्वितीय "टैग" निकालें (प्रतिस्थापन स्ट्रिंग खाली है):

    Search string:<@#-unique-#@>
    Replace string:<nothing>  
    Replace-all  

अब आपके पास मूल पाठ है जिसमें स्ट्रिंग को hedeहटाए जाने वाली सभी लाइनें हैं ।


अगर मैं केवल लाइनों के लिए कुछ करने के लिए देख रहा हूँ जिसमें स्ट्रिंग नहीं है hede, तो मैं इसे इस तरह से करूँगा:

1. किसी भी पाठ वाले प्रत्येक पंक्ति की शुरुआत में एक अद्वितीय "टैग" जोड़ने के लिए संपूर्ण फ़ाइल खोजें / बदलें।

    Search string:^(.)  
    Replace string:<@#-unique-#@>\1  
    Replace-all  

2. सभी पंक्तियों के लिए जिसमें स्ट्रिंग है hede, अद्वितीय "टैग" को हटा दें:

    Search string:<@#-unique-#@>(.*hede)
    Replace string:\1  
    Replace-all  

3. इस बिंदु पर, सभी लाइनें जो अद्वितीय "टैग" से शुरू होती हैं, उनमें स्ट्रिंग नहीं होती है hede। मैं अब केवल उन लाइनों के लिए अपने कुछ और कर सकते हैं ।

4. जब मैं किया जाता हूं, मैं सभी लाइनों से अद्वितीय "टैग" हटाता हूं (प्रतिस्थापन स्ट्रिंग खाली है):

    Search string:<@#-unique-#@>
    Replace string:<nothing>  
    Replace-all  

12

चूंकि किसी और ने पूछे गए सवाल का सीधा जवाब नहीं दिया , इसलिए मैं इसे करूंगा।

इसका उत्तर यह है कि POSIX के साथ grep, इस अनुरोध को सचमुच पूरा करना असंभव है:

grep "<Regex for 'doesn't contain hede'>" input

इसका कारण यह है कि POSIX grepको केवल बेसिक रेगुलर एक्सप्रेशंस के साथ काम करने की आवश्यकता होती है , जो केवल उस कार्य को पूरा करने के लिए पर्याप्त शक्तिशाली नहीं होते हैं (वे वैकल्पिक भाषाओं और पेरेंटेस की कमी के कारण नियमित भाषाओं को पार्स करने में सक्षम नहीं होते हैं)।

हालांकि, जीएनयू grepविस्तार को लागू करता है जो इसे अनुमति देता है। विशेष रूप से, \|बीआरईएस के जीएनयू के क्रियान्वयन में प्रत्यावर्तन ऑपरेटर है, और \(और \)कोष्ठकों हैं। यदि आपका नियमित अभिव्यक्ति इंजन वैकल्पिक, नकारात्मक ब्रैकेट भाव, कोष्ठक और क्लेन स्टार का समर्थन करता है, और स्ट्रिंग की शुरुआत और अंत में लंगर डालने में सक्षम है, तो आपको इस दृष्टिकोण की आवश्यकता है। ध्यान दें कि नकारात्मक सेट [^ ... ]उन लोगों के अलावा बहुत सुविधाजनक हैं, क्योंकि अन्यथा, आपको उन्हें उस फॉर्म की अभिव्यक्ति के साथ बदलने की ज़रूरत है (a|b|c| ... )जो हर चरित्र को सूचीबद्ध करता है जो सेट में नहीं है, जो बेहद थकाऊ और पीढ़ी से लंबा है, और भी बहुत कुछ पूरा चरित्र सेट यूनिकोड है।

GNU के साथ grep, उत्तर कुछ इस प्रकार होगा:

grep "^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$" input

( ग्रिल के साथ मिला और हाथ से किए गए कुछ और अनुकूलन)।

आप ऐसे टूल का भी उपयोग कर सकते हैं , जो रेगुलर एक्सप्रेशंस को लागू करता है , जैसे egrep, बैकस्लैश से छुटकारा पाने के लिए:

egrep "^([^h]|h(h|eh|edh)*([^eh]|e[^dh]|ed[^eh]))*(|h(h|eh|edh)*(|e|ed))$" input

इसकी जांच करने के लिए एक स्क्रिप्ट यहां दी गई है (ध्यान दें कि यह testinput.txtवर्तमान निर्देशिका में एक फ़ाइल उत्पन्न करता है ):

#!/bin/bash
REGEX="^\([^h]\|h\(h\|eh\|edh\)*\([^eh]\|e[^dh]\|ed[^eh]\)\)*\(\|h\(h\|eh\|edh\)*\(\|e\|ed\)\)$"

# First four lines as in OP's testcase.
cat > testinput.txt <<EOF
hoho
hihi
haha
hede

h
he
ah
head
ahead
ahed
aheda
ahede
hhede
hehede
hedhede
hehehehehehedehehe
hedecidedthat
EOF
diff -s -u <(grep -v hede testinput.txt) <(grep "$REGEX" testinput.txt)

मेरे सिस्टम में यह प्रिंट करता है:

Files /dev/fd/63 and /dev/fd/62 are identical

जैसा सोचा था।

विवरण में रुचि रखने वालों के लिए, नियोजित तकनीक नियमित अभिव्यक्ति को बदलने के लिए है जो शब्द को एक परिमित ऑटोमेटन में बदल देती है, फिर हर स्वीकृति स्थिति को गैर-स्वीकृति और इसके विपरीत में बदलकर ऑटोमेटन को उलट देती है, और फिर परिणामी एफए को वापस परिवर्तित करती है। एक नियमित अभिव्यक्ति।

अंत में, जैसा कि सभी ने नोट किया है, यदि आपका नियमित अभिव्यक्ति इंजन नकारात्मक रूपांतर का समर्थन करता है, जो कार्य को बहुत सरल करता है। उदाहरण के लिए, GNU grep के साथ:

grep -P '^((?!hede).)*$' input

अपडेट: मुझे हाल ही में PHP में लिखी केंडल हॉपकिंस की उत्कृष्ट फॉर्मल थ्योरी लाइब्रेरी मिली है , जो ग्रिल के समान एक कार्यक्षमता प्रदान करती है। इसका उपयोग करते हुए, और खुद के द्वारा लिखा गया एक सरलीकृत, मैं एक नियमित वाक्यांश के ऑनलाइन जनरेटर को लिखने में सक्षम हूं, जो एक इनपुट वाक्यांश (वर्तमान में समर्थित केवल अल्फ़ान्यूमेरिक और अंतरिक्ष वर्ण) दिए गए हैं: http://www.formauri.es/personal/ pgimeno / विविध / गैर मैच regex /

इसके लिए hedeआउटपुट:

^([^h]|h(h|e(h|dh))*([^eh]|e([^dh]|d[^eh])))*(h(h|e(h|dh))*(ed?)?)?$

जो ऊपर के बराबर है।


11

रूबी-2.4.1 की शुरूआत के बाद से, हम रूबी की नियमित अभिव्यक्तियों में नए अनुपस्थित ऑपरेटर का उपयोग कर सकते हैं

आधिकारिक डॉक्टर से

(?~abc) matches: "", "ab", "aab", "cccc", etc.
It doesn't match: "abc", "aabc", "ccccabc", etc.

इस प्रकार, आपके मामले में आपके ^(?~hede)$लिए काम करता है

2.4.1 :016 > ["hoho", "hihi", "haha", "hede"].select{|s| /^(?~hede)$/.match(s)}
 => ["hoho", "hihi", "haha"]

9

पीसीआरई क्रिया के माध्यम से (*SKIP)(*F)

^hede$(*SKIP)(*F)|^.*$

यह उस रेखा को पूरी तरह से छोड़ देता है जिसमें सटीक स्ट्रिंग होती है hedeऔर सभी शेष रेखाओं से मेल खाती है।

डेमो

भागों का निष्पादन:

आइए हम उपरोक्त रेगेक्स को दो भागों में विभाजित करके विचार करें।

  1. |प्रतीक से पहले का भाग । भाग का मिलान नहीं किया जाना चाहिए

    ^hede$(*SKIP)(*F)
  2. |प्रतीक के बाद का भाग । भाग का मिलान किया जाना चाहिए

    ^.*$

भाग 1

रेगेक्स इंजन पहले भाग से अपना निष्पादन शुरू करेगा।

^hede$(*SKIP)(*F)

स्पष्टीकरण:

  • ^ कहते हैं कि हम शुरुआत में हैं।
  • hede तार से मेल खाता है hede
  • $ दावा करता है कि हम लाइन के अंत में हैं।

तो जिस लाइन में स्ट्रिंग hedeहोती है उसका मिलान किया जाएगा। एक बार रेगेक्स इंजन निम्नलिखित देखता है (*SKIP)(*F)( नोट: आप इस (*F)रूप में लिख सकते हैं(*FAIL) ) क्रिया, यह रुक जाती है और मैच को विफल कर देती है। |परिवर्तन या तार्किक या ऑपरेटर कहा जाता है जिसे PCRE क्रिया के बगल में जोड़ा जाता है जो कि सभी सीमाओं से मेल खाती है, सभी रेखाओं के बीच प्रत्येक रेखा के बीच मौजूद होती है सिवाय रेखा के जिसमें सटीक स्ट्रिंग होती है hede। डेमो यहाँ देखें । यही है, यह शेष स्ट्रिंग के पात्रों से मेल खाने की कोशिश करता है। अब दूसरे भाग में रेगेक्स को निष्पादित किया जाएगा।

भाग 2

^.*$

स्पष्टीकरण:

  • ^ कहते हैं कि हम शुरुआत में हैं। यानी, यह लाइन के एक को छोड़कर सभी लाइन से मेल खाता है hede। डेमो यहाँ देखें ।
  • .*मल्टीलाइन मोड में, .न्यूलाइन या कैरिज रिटर्न वर्णों को छोड़कर किसी भी वर्ण से मेल खाएगा। और *पिछले चरित्र को शून्य या अधिक बार दोहराएगा। तो .*पूरी लाइन से मेल खाती। डेमो यहाँ देखें ।

    अरे आपने क्यों जोड़ा। * के बजाय। +

    क्योंकि .*एक रिक्त रेखा से मेल खाएगा लेकिन .+एक रिक्त से मेल नहीं खाएगा। हम सभी लाइनों को छोड़ना चाहते हैं hede, इनपुट में रिक्त लाइनों की भी संभावना हो सकती है। इसलिए आप .*इसके बजाय उपयोग करना चाहिए .+.+पिछले चरित्र को एक या अधिक बार दोहराएगा। यहां.* एक रिक्त रेखा से मिलान देखें ।

  • $ लाइन एंकर का अंत यहां आवश्यक नहीं है।


7

यह आपके कोड में दो रेगेक्स के लिए अधिक रख-रखाव करने वाला हो सकता है, पहला मैच करने के लिए, और फिर यदि यह दूसरे रेगेक्स से मेल खाता हो, तो आप ऐसे आउटरी मामलों की जांच कर सकते हैं, जिन्हें आप उदाहरण के लिए ब्लॉक करना चाहते हैं। ^.*(hede).* तो आपके कोड में उपयुक्त तर्क हैं।

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


5

TXR भाषा regex निषेध का समर्थन करता है।

$ txr -c '@(repeat)
@{nothede /~hede/}
@(do (put-line nothede))
@(end)'  Input

एक अधिक जटिल उदाहरण: उन सभी रेखाओं से मेल खाता है जो शुरू होती हैं aऔर साथ समाप्त होती हैं z, लेकिन सबस्ट्रिंग में शामिल नहीं हैं hede:

$ txr -c '@(repeat)
@{nothede /a.*z&~.*hede.*/}
@(do (put-line nothede))
@(end)' -
az         <- echoed
az
abcz       <- echoed
abcz
abhederz   <- not echoed; contains hede
ahedez     <- not echoed; contains hede
ace        <- not echoed; does not end in z
ahedz      <- echoed
ahedz

रेगेक्स नकार अपने आप में विशेष रूप से उपयोगी नहीं है, लेकिन जब आपके पास चौराहा भी होता है, तो चीजें दिलचस्प हो जाती हैं, क्योंकि आपके पास बूलियन सेट ऑपरेशन का एक पूरा सेट है: आप "जो इस से मेल खाते हैं, जो चीजों से मेल खाते हैं, को छोड़कर" व्यक्त कर सकते हैं।


ध्यान दें कि यह ElasticSearch Lucene आधारित regex का समाधान भी है।
विकटोरिया स्ट्राइब्यू

5

एक अन्य विकल्प यह है कि एक सकारात्मक रूप को जोड़ने के लिए और जांचें कि heheक्या इनपुट लाइन में कहीं भी है, तो हम इसे नकार देंगे, एक अभिव्यक्ति के साथ:

^(?!(?=.*\bhede\b)).*$

शब्द सीमाओं के साथ।


अभिव्यक्ति को regex101.com के शीर्ष दाएं पैनल पर समझाया गया है , यदि आप इसे एक्सप्लोर / सरल / संशोधित करना चाहते हैं, और इस लिंक में , आप यह देख सकते हैं कि यह कुछ नमूना इनपुट के विरुद्ध कैसे मेल खाता है, यदि आप चाहें।


RegEx सर्किट

jex.im नियमित अभिव्यक्ति की कल्पना करता है:

यहां छवि विवरण दर्ज करें


4

नीचे दिए गए फ़ंक्शन से आपको अपना वांछित आउटपुट प्राप्त करने में मदद मिलेगी

<?PHP
      function removePrepositions($text){

            $propositions=array('/\bfor\b/i','/\bthe\b/i'); 

            if( count($propositions) > 0 ) {
                foreach($propositions as $exceptionPhrase) {
                    $text = preg_replace($exceptionPhrase, '', trim($text));

                }
            $retval = trim($text);

            }
        return $retval;
    }


?>

2

^ ((हैदर)।) * $ एक सुरुचिपूर्ण समाधान है, सिवाय इसके कि यह उन पात्रों का उपभोग करता है जिन्हें आप अन्य मानदंडों के साथ संयोजित नहीं कर पाएंगे। उदाहरण के लिए, मान लें कि आप "हैड" की गैर-मौजूदगी और "हाहा" की उपस्थिति की जांच करना चाहते हैं। यह समाधान काम करेगा क्योंकि यह पात्रों का उपभोग नहीं करेगा:

^ ^! (। \ bhede \ b) (?! =। \ bhaha \ b)


1

कैसे एक शब्द से युक्त लाइन से मेल करने के लिए पीसीआरई के बैकट्रैकिंग नियंत्रण क्रियाओं का उपयोग करें

यहाँ एक विधि है जो मैंने पहले नहीं देखी है:

/.*hede(*COMMIT)^|/

यह काम किस प्रकार करता है

सबसे पहले, यह लाइन में कहीं "हेज" खोजने की कोशिश करता है। यदि इस बिंदु पर सफल होता है, (*COMMIT)तो इंजन को बताता है, न केवल विफलता की स्थिति में पीछे नहीं, बल्कि उस मामले में आगे किसी भी मिलान का प्रयास करने के लिए भी नहीं। फिर, हम कुछ ऐसा मिलान करने का प्रयास करते हैं जो संभवतः मेल नहीं खा सकता है (इस मामले में ^)।

यदि एक पंक्ति में "हैड" नहीं होता है, तो दूसरा विकल्प, एक खाली उपपट्ट, विषय स्ट्रिंग से सफलतापूर्वक मेल खाता है।

यह विधि एक नकारात्मक रूपांतर से अधिक कुशल नहीं है, लेकिन मुझे लगा कि मैं इसे सिर्फ यहाँ फेंक दूंगा अगर कोई इसे निफ्टी पाता है और अन्य, अधिक दिलचस्प अनुप्रयोगों के लिए इसका उपयोग करता है।


0

एक सरल समाधान ऑपरेटर का उपयोग नहीं करना है !

यदि आपका कथन "समाहित" से मेल खाता है, तो "अपवर्जित" से मेल नहीं खाना चाहिए।

var contains = /abc/;
var excludes =/hede/;

if(string.match(contains) && !(string.match(excludes))){  //proceed...

मेरा मानना ​​है कि RegEx के डिजाइनरों ने ऑपरेटरों के उपयोग का अनुमान लगाया था।


0

हो सकता है कि आप Google पर एक ऐसा रेगेक्स लिखने की कोशिश कर रहे हों जो एक पंक्ति के खंडों के रूप में मिलान करने में सक्षम हो (पूरी लाइनों के विपरीत) जिसमें एक विकल्प नहीं है। मुझे पता लगाने में थोड़ा समय लगा, इसलिए मैं साझा करूंगा:

एक स्ट्रिंग दिया: <span class="good">bar</span><span class="bad">foo</span><span class="ugly">baz</span>

मैं उन <span>टैगों का मिलान करना चाहता हूं जिनमें "खराब" विकल्प नहीं है।

/<span(?:(?!bad).)*?> मैच होगा <span class=\"good\"> और <span class=\"ugly\">

ध्यान दें कि कोष्ठक के दो सेट (परत) हैं:

  • अंतरतम एक नकारात्मक रूपांतर के लिए है (यह एक कैप्चर समूह नहीं है)
  • सबसे बाहरी की व्याख्या रूबी ने कैप्चर ग्रुप के रूप में की थी, लेकिन हम नहीं चाहते कि यह एक कैप्चर ग्रुप हो, इसलिए मैंने जोड़ा ;: यह शुरुआत में है और इसे अब कैप्चर ग्रुप के रूप में नहीं समझा जाता है।

रूबी में डेमो:

s = '<span class="good">bar</span><span class="bad">foo</span><span class="ugly">baz</span>'
s.scan(/<span(?:(?!bad).)*?>/)
# => ["<span class=\"good\">", "<span class=\"ugly\">"]

0

ConyEdit के साथ , आप उन cc.gl !/hede/पंक्तियों को प्राप्त करने के लिए कमांड लाइन का उपयोग कर सकते हैं जिनमें रेगेक्स मिलान नहीं है, या रीजैक्स मिलान वाले cc.dl /hede/लाइनों को हटाने के लिए कमांड लाइन का उपयोग करें । उनका एक ही परिणाम है।


0

मैं एक और उदाहरण जोड़ना चाहता था यदि आप एक पूरी पंक्ति से मेल खाने की कोशिश कर रहे हैं जिसमें स्ट्रिंग X शामिल है , लेकिन इसमें स्ट्रिंग Y भी नहीं है

उदाहरण के लिए, मान लें कि हम यह जांचना चाहते हैं कि हमारे URL / स्ट्रिंग में " स्वादिष्ट व्यवहार " है या नहीं, जब तक कि उसमें " चॉकलेट " भी न हो।

यह रेगेक्स पैटर्न काम करेगा (जावास्क्रिप्ट में भी काम करता है)

^(?=.*?tasty-treats)((?!chocolate).)*$

(उदाहरण में वैश्विक, बहुभाषी झंडे)

इंटरएक्टिव उदाहरण: https://regexr.com/53gv4

माचिस

(इन उबलों में "स्वादिष्ट व्यवहार" होते हैं और "चॉकलेट" भी नहीं होते हैं)

  • example.com/tasty-treats/strawberry-ice-cream
  • example.com/desserts/tasty-treats/banana-pudding
  • example.com/tasty-treats-overview

मिलता जुलता नहीं है

(इन यूआरएल में कहीं "चॉकलेट" शामिल हैं - इसलिए वे "स्वादिष्ट व्यवहार" होते हुए भी मेल नहीं खाते

  • example.com/tasty-treats/chocolate-cake
  • example.com/home-cooking/oven-roasted-chicken
  • example.com/tasty-treats/banana-chocolate-fudge
  • example.com/desserts/chocolate/tasty-treats
  • example.com/chocolate/tasty-treats/desserts
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.