एक Regex जो किसी भी चीज़ से कभी मेल नहीं खाएगा


131

यह एक बेवकूफ सवाल की तरह लग सकता है, लेकिन मैंने अपने कुछ साथी डेवलपर्स के साथ लंबी बात की और यह सोचने के लिए एक मजेदार बात की तरह लग रहा था।

इसलिए; आपका क्या विचार है - एक रेक्सक्स कैसा दिखता है, जो कभी भी किसी स्ट्रिंग द्वारा मेल नहीं खाया जाएगा!

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

उस लिपि में मैं एक डिक्शनरी को परिभाषित करता हूं Dictionary<string, Regex>। इसमें शामिल है, जैसा कि आप देखते हैं, एक स्ट्रिंग और एक अभिव्यक्ति।

उस शब्दकोश के आधार पर, मैं ऐसे तरीके बनाता हूँ जो सभी इस शब्दकोश का उपयोग केवल संदर्भ के रूप में करते हैं कि उन्हें अपना काम कैसे करना चाहिए, उनमें से एक पार्स लॉगफ़ाइल के खिलाफ रेक्सक्स से मेल खाता है।

यदि एक अभिव्यक्ति का मिलान किया जाता है, तो एक और Dictionary<string, long>मान जोड़ा जाता है जो कि अभिव्यक्ति द्वारा लौटाया जाता है। इसलिए, किसी भी लॉग-मैसेज को पकड़ने के लिए, जो शब्दकोश में एक अभिव्यक्ति से मेल नहीं खाता है, मैंने "अज्ञात" नामक एक नया समूह बनाया।

इस समूह के लिए वह सब कुछ जो किसी और चीज से मेल नहीं खाता, जोड़ा जाता है। लेकिन लॉग-मैसेज करने के लिए "अज्ञात" -एक्सप्रेशन को बेमेल (दुर्घटना से) रोकने के लिए, मुझे एक अभिव्यक्ति बनानी होगी जो निश्चित रूप से कभी भी मेल नहीं खाती है, चाहे मैं इसे कितना भी स्ट्रिंग दूं।

इस प्रकार, वहाँ आप इस "एक असली सवाल नहीं" के लिए मेरे कारण है ...


1
ध्यान दें कि नकारात्मक साबित करना बहुत कठिन है।
लास वी। कार्लसन

5
दिलचस्प। आप इस तरह के रेगेक्स का उपयोग कहां करेंगे?
चार्ली साल्ट्स

1
मैं यहाँ उस रिकॉर्ड के लिए नोट करूंगा, जिसमें ऊपर की कई टिप्पणियाँ और इस प्रश्न के उत्तर मूल रूप से stackoverflow.com/questions/1845078/… से थे, जो कि मैंने पूछा था। मार्क ग्रेवेल ने उन्हें विलय कर दिया, जो मुझे लगता है कि इनमें से कई प्रतिक्रियाएं सटीक मूल संदर्भ के बिना विचित्र तरह की हैं, कुछ टिप्पणियों से समझ में नहीं आता है। (संभवतया संभावित भविष्य के रेप पॉइंट्स को भी चुरा लेता है।) मैं सुझाव दूंगा कि इस तरह की विस्तृत पृष्ठभूमि वाले प्रश्न कभी "सटीक डुप्लिकेट" नहीं हो सकते हैं। जो भी हो ...
पीटर हेन्सन

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

3
"ध्यान दें कि नकारात्मक साबित करना बहुत कठिन है" - यह व्यापक रूप से अभी तक पूरी तरह से और स्पष्ट रूप से गलत माना जाता है ... जैसा कि हम कम से कम जानते हैं क्योंकि यूक्लिड ने साबित कर दिया कि कोई सबसे बड़ा प्रधानमंत्री नहीं है। और P का कोई भी प्रमाण (P नहीं) की उपेक्षा का प्रमाण है। यह सच है कि एक अनुभवजन्य सार्वभौमिक, सकारात्मक या नकारात्मक साबित करना मुश्किल है, उदाहरण के लिए, "सभी रावण काले हैं" या "कोई भी रावण सफेद नहीं है"। एल्गोरिदम विश्लेषणात्मक हैं, अनुभवजन्य नहीं हैं, इसलिए यह फर्जी नियम का विशेष रूप से खराब दुरुपयोग है। उदाहरण के लिए, एक प्रमाण कि 'a' किसी भी स्ट्रिंग से मेल नहीं खाता है जो 'b' से शुरू होता है "बहुत कठिन" नहीं है।
जिम बाल्टर

जवाबों:


66

यह वास्तव में काफी सरल है, हालांकि यह कार्यान्वयन / झंडे पर निर्भर करता है *:

$a

aस्ट्रिंग के अंत के बाद एक चरित्र से मेल खाएगा । सौभाग्य।

चेतावनी:
यह अभिव्यक्ति महँगी है - यह पूरी लाइन को स्कैन करेगी, लाइन-ऑफ़-एंकर को खोजेगी, और उसके बाद ही नहीं खोजेगी aऔर एक नकारात्मक मिलान लौटाएगी। (अधिक विस्तार के लिए नीचे टिप्पणी देखें।)


* मूल रूप से मैंने मल्टीलाइन-मोड रेगेक्सपी पर ज्यादा विचार नहीं दिया, जहां $एक पंक्ति के अंत से भी मेल खाता है। वास्तव में, यह न्यूलाइन से ठीक पहले खाली स्ट्रिंग से मेल खाता है , इसलिए एक साधारण चरित्र की तरह aकभी भी दिखाई नहीं दे सकता है $


50
यह अभिव्यक्ति महंगी है - यह पूरी लाइन को स्कैन करेगा, अंत-पंक्ति के एंकर को ढूंढेगा, और उसके बाद ही "ए" नहीं ढूंढेगा और एक नकारात्मक मैच लौटाएगा। मैं इसे ~ 275k लाइन फ़ाइल को स्कैन करने के लिए ~ 480ms लेता हूं। "एक ^" का रूपांतरण एक ही समय के बारे में है, भले ही यह अधिक कुशल लग सकता है। दूसरी ओर, एक नकारात्मक लुकहेड को कुछ भी स्कैन करने की आवश्यकता नहीं है: "(?! X) x" (एक्स के बाद कुछ भी नहीं एक्स के बाद कुछ भी नहीं) यानी लगभग 30ms, या 7% से कम समय लगता है। (ग्नू समय और
एग्रेप के

1
पर्ल में जो वर्तमान मूल्य से मेल खाएगा $a। यह पर्ल समतुल्य $(?:a)भी बहुत धीमा है perl -Mre=debug -e'$_=a x 50; /$(?:a)/'
ब्रैड गिल्बर्ट

@arantius, कृपया समय के संबंध में मेरा उत्तर देखें , क्योंकि मुझे इसके साथ मापा गया सटीक पता चला timeitऔर python3
nivk

यह चौंकाने वाला नहीं है कि छह साल और पायथन का एक प्रमुख संस्करण चीजों को बदल सकता है।
arantius

1
POSIX BRE सिंटैक्स में, $aशाब्दिक पाठ से मेल खाएगा $a, क्योंकि $उस पैटर्न में एक एंकर के रूप में अमान्य है।
फिल्स

76

उत्तोलन negative lookahead:

>>> import re
>>> x=r'(?!x)x'
>>> r=re.compile(x)
>>> r.match('')
>>> r.match('x')
>>> r.match('y')

यह आरईआर एक विरोधाभास है और इसलिए यह कभी भी मेल नहीं खाएगा।

नोट:
पायथन में, re.match ()\A नियमित अभिव्यक्ति की शुरुआत में एक शुरुआत-से-स्ट्रिंग लंगर ( ) जोड़ता है । यह एंकर प्रदर्शन के लिए महत्वपूर्ण है: इसके बिना, पूरे स्ट्रिंग को स्कैन किया जाएगा। पायथन का उपयोग नहीं करने वाले स्पष्ट रूप से लंगर जोड़ना चाहेंगे:

\A(?!x)x

@ क्रिस, येप - (?=x)(?!x)और भी, (विरोधाभासी लुकहेड्स के रूपांतर, और लुकहाइबेंड्स के लिए समान), और उनमें से कई भी मनमाने मूल्यों के लिए काम करते हैं x(लुकहाइंड्स xको निश्चित लंबाई के मिलान की आवश्यकता होती है)।
एलेक्स मार्टेली

1
अच्छा काम करने की अपील करता है। लेकिन इसके बजाय सिर्फ (?) के बारे में क्या? चूंकि () हमेशा मैच करेगा, (?) की गारंटी कभी मैच नहीं की जाएगी?
पीटर हैनसेन

2
@ पेटर, हाँ, अगर पायथन उस वाक्य रचना को स्वीकार करता है (और हाल ही में रिलीज़ होता है), तो यह आत्म-विरोधाभासी भी होगा। एक अन्य विचार (काफी सुरुचिपूर्ण नहीं है, लेकिन जितने अधिक विचार आपको पसंद आते हैं, आपको सभी आरई इंजनों के हित में काम करने वाले हैं): r'a\bc'एक शब्द-सीमा की तलाश में तुरंत दोनों पक्षों के पत्रों से घिरा हुआ है (संस्करण: नॉनवर्ड अक्षर दोनों पक्षों)।
एलेक्स मार्टेली

1
दिलचस्प बात यह है कि, एक साधारण शाब्दिक शब्द जिसे मैं "जानता हूं" के साथ मेरा मूल मेरे इनपुट में प्रकट नहीं होगा, पायथन में सबसे तेज़ हो जाता है। 5MB इनपुट स्ट्रिंग के साथ, और एक सब () ऑपरेशन में इसका उपयोग करते हुए, (? X) x में 21% लंबा समय लगता है, (? -)) 16% है, और ($ ^) 6% लंबा है। कुछ मामलों में महत्वपूर्ण हो सकता है, हालांकि मेरा नहीं है।
पीटर हैनसेन

2
यह काफी धीमा हो सकता है perl -Mre=debug -e'$_=x x 8; /(?!x)x/'। आप इसे शुरुआत में \A(?!x)xया अंत में एंकरिंग करके तेज़ बना सकते हैं (?!x)x\zperl -Mre=debug -e'$_=x x 8; /(?!x)x\z/; /\A(?!x)x/'
ब्रैड गिल्बर्ट

43

एक कि याद किया गया था:

^\b$

यह मेल नहीं कर सकता क्योंकि खाली स्ट्रिंग में शब्द सीमा नहीं है। पायथन 2.5 में परीक्षण किया गया।


7
यह सबसे अच्छा जवाब है। यह लुकहेड्स का उपयोग नहीं करता है, कुछ रेगेक्स कार्यान्वयन के तहत नहीं टूटता है, एक विशिष्ट चरित्र (जैसे 'ए') का उपयोग नहीं करता है, और पूरे स्कैन किए बिना अधिकतम 3 प्रसंस्करण चरणों (regex101.com के अनुसार) में विफल रहता है इनपुट स्ट्रिंग। एक नज़र में समझना भी आसान है।
क्यूबिकलसॉफ्ट

1
यह वास्तव में कुछ स्थितियों में Emacs में विफल रहता है (यदि बफर की शुरुआत या अंत में एक रिक्त रेखा है), हालांकि \`\b\'काम करता है, जो "पाठ की शुरुआत / अंत" के लिए Emacs सिंटैक्स को प्रतिस्थापित कर रहा है (जैसा कि "शुरुआत और अंत के विपरीत)" की रेखा")।
फिल्स

35

चारों ओर देखो:

(?=a)b

Regex newbies के लिए: आगे का सकारात्मक लुक (?=a)यह सुनिश्चित करता है कि अगला चरित्र है a, लेकिन खोज स्थान को नहीं बदलता है (या मिलान किए गए स्ट्रिंग में 'a' को शामिल करता है)। अब जब अगला चरित्र होने की पुष्टि हो जाती है a, तो रेगेक्स का शेष हिस्सा ( b) तभी मेल खाता है जब अगला चरित्र है b। इस प्रकार, यह रेगेक्स केवल तभी मेल खाता है जब एक चरित्र दोनों aऔर bएक ही समय में हो।


30

a\bc, जहां \bएक शून्य-चौड़ाई की अभिव्यक्ति है जो शब्द सीमा से मेल खाती है।

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


यदि आपका उपयोग-मामला आपको पैटर्न को स्ट्रिंग की शुरुआत में लंगर करने की अनुमति देता है, तो यह एन्हांसमेंट rexxp इंजन aको टेक्स्ट में हर उदाहरण को खोजने और परीक्षण करने से रोकेगा ।
फिल्स

20

$.

.^

$.^

(?!)


1
प्यारा! मेरे अवचेतन ने मुझे पहले तीन जैसे विचारों से दूर कर दिया, क्योंकि वे "गैरकानूनी" हैं ... वैचारिक रूप से, लेकिन स्पष्ट रूप से पुनर्जन्म के लिए नहीं। मैं (!) को नहीं पहचानता ... एक को देखना होगा।
पीटर हेन्सन

1
ठीक है फिर, मुझे एक (!) उत्तर पसंद है ... प्रभावी रूप से एलेक्स ने क्या सुझाव दिया। ध्यान दें कि stackoverflow.com/questions/1723182 (ऊपर अमरघोष द्वारा इंगित) में कहा गया है कि कोई भी रेगेक्स के "कुछ स्वादों" का दावा करता है कि एक वाक्यविन्यास त्रुटि होगी। अजगर हालांकि यह ठीक पसंद करता है। ध्यान दें कि पायथन में आपके अन्य सुझाव re.DOTALL | re.MULTILINE मोड के साथ विफल हो जाएंगे।
पीटर हैनसेन

1
क्या यह परीक्षण किया गया है? मैंने यह मान लिया होगा कि ^केवल एक विशेष अर्थ है एक regexp के पहले चरित्र के रूप में, और $केवल एक regexp के अंत में विशेष अर्थ है, जब तक कि नियमित अभिव्यक्ति एक बहु-पंक्ति अभिव्यक्ति नहीं है।
पीपी।

वास्तव में पर्ल का /$./मतलब कुछ अलग है। इसका मतलब $.(इनपुट लाइन नंबर) के वर्तमान मूल्य से मेल खाता है । यहां तक ​​कि /$(.)/अगर आप use re '/s';इससे पहले लिखा था कि कुछ भी मैच कर सकते हैं । ( perl -E'say "\n" =~ /$(.)/s || 0')
ब्रैड गिल्बर्ट

POSIX BRE वाक्य रचना में, ^और $पैटर्न के शुरुआत और अंत (क्रमशः) पर केवल विशेष हैं, इसलिए में से कोई भी $.या .^या $.^काम करेगा। (?!)एक पर्ल / पीसीआरई सुविधा है, मेरा मानना ​​है।
फिल्स

13

मैक्सिमम मैचिंग

a++a

aकिसी भी संख्या में कम से कम एक के बाद a, बिना पीछे के। फिर एक और मैच करने की कोशिश करें a

या स्वतंत्र उप अभिव्यक्ति

यह a+एक स्वतंत्र उप अभिव्यक्ति में डालने के बराबर है , दूसरे के बाद a

(?>a+)a

10

पर्ल 5.10 "क्रिया" नामक विशेष नियंत्रण शब्दों का समर्थन करता है, जो (*...)अनुक्रम में संलग्न है । ( (?...)विशेष अनुक्रम के साथ तुलना करें ।) उनमें से, इसमें (*FAIL)क्रिया शामिल है जो नियमित अभिव्यक्ति से तुरंत लौटती है।

ध्यान दें कि पीसीआरई में कुछ ही समय बाद क्रियाओं को भी लागू किया जाता है, इसलिए आप उन्हें PHP या अन्य भाषाओं में भी PCRE लाइब्रेरी का उपयोग कर सकते हैं। (हालांकि, आप पायथन या रूबी में नहीं हो सकते। वे अपने स्वयं के इंजन का उपयोग करते हैं।)


इसके लिए डॉक्स perldoc.perl.org/perlre.html#%28%2AFAIL%29-%28%2AF%29 पर कहते हैं, "यह पैटर्न कुछ नहीं और हमेशा विफल रहता है। यह (!) के बराबर है, लेकिन आसान है। पढ़ें। वास्तव में, (!) आंतरिक रूप से (* विफल) में अनुकूलित हो जाता है। " दिलचस्प है, (!) मेरा पसंदीदा "शुद्ध" उत्तर है अब तक (भले ही यह जावास्क्रिप्ट में काम नहीं करता है)। धन्यवाद।
पीटर हैनसेन

10
\B\b

\bशब्द सीमाओं से मेल खाता है - एक पत्र के बीच की स्थिति एक गैर-पत्र (या स्ट्रिंग सीमा)।
\Bइसका पूरक है - यह दो अक्षरों के बीच या गैर-अक्षरों के बीच की स्थिति से मेल खाता है।

साथ में वे किसी भी स्थिति से मेल नहीं खा सकते हैं।

यह सभी देखें:


यह एक उत्कृष्ट समाधान की तरह लगता है, बशर्ते कि यह एक विशिष्ट बिंदु पर लंगर डाले (पाठ की शुरुआत समझदार प्रतीत होगी)। यदि आप ऐसा नहीं करते हैं, तो यह एक भयानक समाधान है, क्योंकि पाठ में प्रत्येक गैर-शब्द सीमा का परीक्षण यह देखने के लिए किया जाएगा कि क्या यह शब्द सीमा के बाद है! तो समझदार संस्करण कुछ इस तरह होगा ^\B\b। उन भाषाओं में जहां "पाठ की शुरुआत" और "लाइन की शुरुआत" में अलग-अलग वाक्यविन्यास हैं, आप "पाठ की शुरुआत" वाक्यविन्यास का उपयोग करना चाहेंगे, अन्यथा आप हर पंक्ति का परीक्षण करेंगे। (Emacs में जैसे इस होगा \`\B\bया "\\`\\B\\b"।)
फिल्स

उस ने कहा, मैंने अब नोट किया है कि इस प्रश्न का घोषित उद्देश्य एक समूह में उपयोग के लिए एक regexp प्राप्त करना है, जिसमें ^कुछ regexp वाक्यविन्यास (जैसे POSIX BRE) में समस्याग्रस्त है जहां ^केवल एक एंकर है जब यह पहला चरित्र है। पैटर्न का, और अन्यथा एक शाब्दिक ^चरित्र से मेल खाता है ।
फिल्स

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

पुन: अनुकूलन, मैं एक regexp इंजन किसी अन्य स्थान पर "पाठ की शुरुआत" खोजने के लिए उम्मीद है जो अनदेखी करने के लिए तैयार हूँ :)
फिल्स

इसके अलावा, यह ऐसा अव्यावहारिक क्यू एंड ए नहीं है - एकमात्र कारण जो मैंने यहां समाप्त किया, वह यह देखने के लिए था कि क्या कोई विशेष एमएसीएस चर को कॉन्फ़िगर करने के व्यावहारिक उद्देश्य के लिए अपने स्वयं के लिए एक अधिक कुशल समाधान सुझा सकता है जिसे एक regexp मान की आवश्यकता थी , लेकिन मैं जो प्रभावी ढंग से निष्क्रिय करना चाहता था।
फिल्स

8

यह काम करने लगता है:

$.

2
यह फर्डिनेंड बेयर के उदाहरण के समान है।
गम्बू

9
और यह डॉट-मैच-न्यूलाइन्स मोड में मैच करेगा।
टिम Pietzcker

पर्ल में जो वास्तव में वर्तमान इनपुट लाइन नंबर के खिलाफ मैच करेगा $.। उस स्थिति में आपको $(.)या अधिक समान रूप से सहारा लेना होगा $(?:.)
ब्रैड गिल्बर्ट

POSIX BRE सिंटैक्स में, किसी भी वर्ण के बाद $.एक शाब्दिक मिलान करेगा $, क्योंकि $उस पैटर्न में एक एंकर के रूप में अमान्य है।
फिल्स

8

कैसे $^या शायद (?!)


3
एक पंक्ति विराम इस अभिव्यक्ति द्वारा उस विधा से ^मेल खाएगा जहां $एक पंक्ति के आरंभ और अंत से मेल खाता है ।
गंबू 3

4
शायद उनका मतलब था (?!)- एक खाली स्ट्रिंग के लिए एक नकारात्मक लुकहेड। लेकिन कुछ रेगेक्स फ्लेवर्स को एक सिंटैक्स त्रुटि के रूप में भी माना जाएगा।
एलन मूर

1
एक खाली स्ट्रिंग पहले मेल खाता है, कम से कम जावास्क्रिप्ट में।
रोलैंड पिहलकास

POSIX BRE वाक्य रचना में, $^क्योंकि पात्रों एंकर के रूप में अमान्य हैं, उन शाब्दिक वर्णों के अनुरूप होगा (यानी बहुत कारण आप पैटर्न का इस्तेमाल यह है कि तुम क्या चाहते थे नहीं कर कारण बनता है।)
फिल्स

5

सबसे तेज़ होगा:

r = re.compile(r'a^')
r.match('whatever')

'ए' कोई भी गैर-विशेष चरित्र हो सकता है ('x', 'y')। Knio का कार्यान्वयन थोड़ा अधिक शुद्ध हो सकता है, लेकिन यह सभी स्ट्रिंग्स के लिए तेज़ होगा, जो आप 'a' के बजाय जो भी वर्ण चुनते हैं, उसके साथ शुरू नहीं करेंगे क्योंकि यह उन मामलों में दूसरे के बजाय पहले वर्ण के बाद मेल नहीं खाएगा।


वास्तव में, (। ^) मेरे मामले में (\ x00 ^) की तुलना में लगभग 10% धीमा होगा।
पीटर हेन्सन

1
मैं इसे स्वीकार कर रहा हूं, क्योंकि वर्ण के अलावा किसी भी मूल्य का उपयोग करने की गारंटी है क्योंकि चरित्र कभी भी मेल नहीं खाता है, और मैं इसे (! X) x विकल्प की तुलना में थोड़े अधिक पठनीय (अपेक्षाकृत कुछ लोग regex विशेषज्ञ हैं) के रूप में देखते हैं! , हालांकि मैंने वोट दिया कि एक भी। मेरे मामले में, या तो विकल्प के लिए मुझे इसे समझाने के लिए एक टिप्पणी की आवश्यकता होगी, इसलिए मुझे लगता है कि मैं अपने मूल प्रयास को '\ x00NEVERMATCHES ^' में समायोजित करूंगा। मुझे अपने मूल स्व-दस्तावेज-नेस के साथ, इस उत्तर की कोई भी मैच की गारंटी नहीं है। उत्तर के लिए सभी को धन्यवाद!
पीटर हैनसेन

3
क्या यह वास्तव में काम करता है और यदि हां, तो किसने यूनिक्स के साथ तोड़ने का फैसला किया? यूनिक्स रीगेक्स में, ^केवल पहले चरित्र के समान और इसी तरह से विशेष है $। किसी भी यूनिक्स टूल के साथ, वह रेगीक्सप शाब्दिक स्ट्रिंग से युक्त किसी भी चीज़ से मेल खाने वाला है a^
जाकको ११

हेह, यह एक अच्छा हमला है। मैंने उस शाब्दिक स्ट्रिंग के खिलाफ कभी परीक्षण नहीं किया।
एडम नेल्सन

ओह, अगर वह यूनिक्स रेगेक्स को तोड़ता है, तो आप प्यार करेंगे >^
क्यूबिकलसॉफ्ट

4

अजगर इसे स्वीकार नहीं करेगा, लेकिन पर्ल होगा:

perl -ne 'print if /(w\1w)/'

इस regex को (सैद्धांतिक रूप से) s की एक अनंत (सम) संख्या से मेल खाने का प्रयास करना चाहिए w, क्योंकि पहला समूह ( ()s) स्वयं में पुनरावर्ती होता है। पर्ल किसी भी चेतावनी को जारी नहीं करता है, यहां तक ​​कि के तहत use strict; use warnings;, इसलिए मुझे लगता है कि यह कम से कम वैध है, और मेरा (न्यूनतम) परीक्षण कुछ भी मेल करने में विफल रहता है, इसलिए मैं इसे आपके आलोचक के लिए प्रस्तुत करता हूं।


1
सिद्धांत हमेशा अच्छा होता है, लेकिन व्यवहार में मुझे लगता है कि मैं नियमित अभिव्यक्तियों के बारे में चिंतित हूं जिनके विवरण में "अनंत" शब्द शामिल था!
पीटर हैनसेन

perl -Mre=debug -e'"www wwww wwwww wwwwww" =~ /(w\1w)/'
ब्रैड गिल्बर्ट

@ ब्रैडगिल्बर्ट - यहां चल रहा है (5.10, थोड़ा बाहर) "ओपीएक्स विफल" पैदा करता है, जैसा कि ओपी ने अनुरोध किया था। क्या यह आपके सिस्टम पर मेल खाता है?
क्रिस लुट्ज़ 22

4

[^\d\D]या (?=a)bया a$aयाa^a


धन्यवाद। ध्यान दें कि (? X) x पहला उत्तर दिया गया था, जो ऊपर सूचीबद्ध है।
पीटर हैनसेन

हां, ऐसा लगा कि मैंने अन्य उत्तरदाताओं को भी जल्दी से स्कैन किया।
बार्ट कियर्स

4

यह पायथन, और कई अन्य भाषाओं के लिए काम नहीं करेगा, लेकिन एक जावास्क्रिप्ट regex में, []एक वैध चरित्र वर्ग है जिसका मिलान नहीं किया जा सकता है। तो निम्नलिखित को तुरंत विफल होना चाहिए, कोई फर्क नहीं पड़ता कि इनपुट क्या है:

var noMatch = /^[]/;

मुझे इसकी /$a/वजह से अच्छा लगता है, यह स्पष्ट रूप से इसके इरादे को बताता है। और जब आपको कभी इसकी आवश्यकता होगी, तो मुझे इसकी आवश्यकता थी क्योंकि मुझे उपयोगकर्ता इनपुट के आधार पर गतिशील रूप से संकलित पैटर्न के लिए एक कमबैक की आवश्यकता थी। जब पैटर्न अमान्य है, तो मुझे इसे ऐसे पैटर्न से बदलने की आवश्यकता है जो कुछ भी नहीं से मेल खाता हो। सरलीकृत, यह इस तरह दिखता है:

try {
    var matchPattern = new RegExp(someUserInput);
}
catch (e) {
    matchPattern = noMatch;
}

4

एक सीमा मिलान करने वाले सभी उदाहरण एक ही नुस्खा का अनुसरण करते हैं। विधि:

  1. सीमा मिलानकर्ताओं में से कोई भी लें: ^, $, \ b, \ A, \ Z, \ z

  2. वे जो करते हैं उसके विपरीत हैं

उदाहरण:

^ और \ A शुरुआत के लिए हैं इसलिए शुरुआत में उनका उपयोग न करें

^ --> .^
\A --> .\A

\ b एक शब्द सीमा से मेल खाता है इसलिए बीच में इसका उपयोग करें

\b --> .\b.

$, \ Z और \ z अंत के लिए हैं, इसलिए अंत में उनका उपयोग न करें

$ --> $.
\Z --> \Z.
\z --> \z.

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

(?=x)[^x]
(?!x)x

यदि आप किसी चीज के विपरीत सकारात्मक या नकारात्मक रूप देते हैं

[^x](?<=x)
x(?<!x)

उनका पैटर्न इस तरह के और अधिक और अधिक एनालॉग हो सकते हैं।


3

इतने अच्छे जवाब!

@ Nivk के उत्तर के समान, मैं कभी भी मेल न खाने वाले रेगेक्स के विभिन्न संस्करणों के लिए पर्ल के लिए प्रदर्शन तुलना साझा करना चाहूंगा।

  1. इनपुट: छद्म यादृच्छिक अस्की स्ट्रिंग्स (25,000 अलग-अलग लाइनें, लंबाई 8-16):

रेगेक्स की गति:

Total for   \A(?!x)x: 69.675450 s, 1435225 lines/s
Total for       a\bc: 71.164469 s, 1405195 lines/s
Total for    (?>a+)a: 71.218324 s, 1404133 lines/s
Total for       a++a: 71.331362 s, 1401907 lines/s
Total for         $a: 72.567302 s, 1378031 lines/s
Total for     (?=a)b: 72.842308 s, 1372828 lines/s
Total for     (?!x)x: 72.948911 s, 1370822 lines/s
Total for       ^\b$: 79.417197 s, 1259173 lines/s
Total for         $.: 88.727839 s, 1127041 lines/s
Total for       (?!): 111.272815 s, 898692 lines/s
Total for         .^: 115.298849 s, 867311 lines/s
Total for    (*FAIL): 350.409864 s, 285380 lines/s
  1. इनपुट: / usr / शेयर / तानाशाही / शब्द (100,000 अंग्रेजी शब्द)।

रेगेक्स की गति:

Total for   \A(?!x)x: 128.336729 s, 1564805 lines/s
Total for     (?!x)x: 132.138544 s, 1519783 lines/s
Total for       a++a: 133.144501 s, 1508301 lines/s
Total for    (?>a+)a: 133.394062 s, 1505479 lines/s
Total for       a\bc: 134.643127 s, 1491513 lines/s
Total for     (?=a)b: 137.877110 s, 1456528 lines/s
Total for         $a: 152.215523 s, 1319326 lines/s
Total for       ^\b$: 153.727954 s, 1306346 lines/s
Total for         $.: 170.780654 s, 1175906 lines/s
Total for       (?!): 209.800379 s, 957205 lines/s
Total for         .^: 217.943800 s, 921439 lines/s
Total for    (*FAIL): 661.598302 s, 303540 lines/s

(इंटेल i5-3320M पर उबंटू, लिनक्स कर्नेल 4.13, पर्ल 5.26)


यहाँ कुछ तरीकों से जावास्क्रिप्ट की तुलना की गयी है: jsperf.com/regex-that-never-matches
thdoan

2

मेरा मानना ​​है कि

\Z RE FAILS! \A

उन मामलों को भी शामिल करता है जहां नियमित अभिव्यक्ति में MULTILINE, DOTALL आदि जैसे झंडे शामिल हैं।

>>> import re
>>> x=re.compile(r"\Z RE FAILS! \A")
>>> x.match('')
>>> x.match(' RE FAILS! ')
>>>

मुझे विश्वास है (लेकिन मैंने इसे बेंचमार्क नहीं किया है) कि स्ट्रिंग की लंबाई (> 0) के बीच \Zऔर \Aसमय-समय पर विफलता निरंतर होनी चाहिए।



2

इनमें से कुछ महान जवाबों को देखने के बाद, वर्तमान में स्वीकृत उत्तर पर @ arantius की टिप्पणी (समय $xबनाम x^बनाम (?!x)x) के कारण मुझे अब तक दिए गए कुछ समाधानों के लिए समय चाहिए।

@ Arantius के 275k लाइन मानक का उपयोग करते हुए, मैंने पायथन (v3.5.2, IPython 6.2k) में निम्नलिखित परीक्षण चलाए।

TL; DR: 'x^'और 'x\by'कम से कम ~ 16 के एक कारक द्वारा सबसे तेज़ हैं, और @ arantius की खोज के विपरीत, सबसे धीमी (~ 37 गुना धीमी) के (?!x)xबीच था । तो गति प्रश्न निश्चित रूप से कार्यान्वयन पर निर्भर है। यह सुनिश्चित करने के लिए कि गति आपके लिए महत्वपूर्ण है, प्रतिबद्ध करने से पहले अपने इच्छित सिस्टम पर इसका परीक्षण करें।

अद्यतन: स्पष्ट रूप से समय 'x^'और के बीच एक बड़ी विसंगति है 'a^'। कृपया अधिक जानकारी के लिए इस सवाल को देखें , और aइसके बजाय धीमी समय के लिए पिछले संपादित करें x

In [1]: import re

In [2]: with open('/tmp/longfile.txt') as f:
   ...:     longfile = f.read()
   ...:     

In [3]: len(re.findall('\n',longfile))
Out[3]: 275000

In [4]: len(longfile)
Out[4]: 24733175

In [5]: for regex in ('x^','.^','$x','$.','$x^','$.^','$^','(?!x)x','(?!)','(?=x)y','(?=x)(?!x)',r'x\by',r'x\bx',r'^\b$'
    ...: ,r'\B\b',r'\ZNEVERMATCH\A',r'\Z\A'):
    ...:     print('-'*72)
    ...:     print(regex)
    ...:     %timeit re.search(regex,longfile)
    ...:     
------------------------------------------------------------------------
x^
6.98 ms ± 58.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
------------------------------------------------------------------------
.^
155 ms ± 960 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
$x
111 ms ± 2.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
$.
111 ms ± 1.76 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
$x^
112 ms ± 1.14 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
$.^
113 ms ± 1.44 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
$^
111 ms ± 839 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
(?!x)x
257 ms ± 5.03 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
------------------------------------------------------------------------
(?!)
203 ms ± 1.56 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
(?=x)y
204 ms ± 4.84 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
------------------------------------------------------------------------
(?=x)(?!x)
210 ms ± 1.66 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
------------------------------------------------------------------------
x\by
7.41 ms ± 122 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
------------------------------------------------------------------------
x\bx
7.42 ms ± 110 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
------------------------------------------------------------------------
^\b$
108 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
\B\b
387 ms ± 5.77 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
------------------------------------------------------------------------
\ZNEVERMATCH\A
112 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
------------------------------------------------------------------------
\Z\A
112 ms ± 1.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

पहली बार जब मैंने इसे चलाया था, मैं rआखिरी 3 भावों को जगाना भूल गया '\b'था , इसलिए इसकी व्याख्या की गई थी '\x08', बैकस्पेस चरित्र। हालांकि, मेरे आश्चर्य के लिए, 'a\x08c'पिछले सबसे तेज परिणाम से तेज था! निष्पक्ष होने के लिए, यह अभी भी उस पाठ से मेल खाएगा, लेकिन मुझे लगा कि यह अभी भी ध्यान देने योग्य है क्योंकि मुझे यकीन नहीं है कि यह तेज क्यों है।

In [6]: for regex in ('x\by','x\bx','^\b$','\B\b'):
    ...:     print('-'*72)
    ...:     print(regex, repr(regex))
    ...:     %timeit re.search(regex,longfile)
    ...:     print(re.search(regex,longfile))
    ...:     
------------------------------------------------------------------------
y 'x\x08y'
5.32 ms ± 46.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
None
------------------------------------------------------------------------
x 'x\x08x'
5.34 ms ± 66.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
None
------------------------------------------------------------------------
$ '^\x08$'
122 ms ± 1.05 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
None
------------------------------------------------------------------------
\ '\\B\x08'
300 ms ± 4.11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
None

मेरी परीक्षा फ़ाइल "... पढ़ने योग्य सामग्री और कोई डुप्लिकेट लाइनें" के लिए एक सूत्र का उपयोग करके बनाई गई थी (उबंटू 16.04 पर):

$ ruby -e 'a=STDIN.readlines;275000.times do;b=[];rand(20).times do; b << a[rand(a.size)].chomp end; puts b.join(" "); end' < /usr/share/dict/words > /tmp/longfile.txt

$ head -n5 /tmp/longfile.txt 
unavailable speedometer's garbling Zambia subcontracted fullbacks Belmont mantra's
pizzicatos carotids bitch Hernandez renovate leopard Knuth coarsen
Ramada flu occupies drippings peaces siroccos Bartók upside twiggier configurable perpetuates tapering pint paralyzed
vibraphone stoppered weirdest dispute clergy's getup perusal fork
nighties resurgence chafe

\B\bभयंकर रूप से त्रुटिपूर्ण प्रदर्शन-वार है (जैसा कि हर पैटर्न है जो किसी स्थिति के लिए लंगर डाले नहीं है, लेकिन यह पैटर्न विशेष रूप से खराब है)। ^\B\bइसके बजाय बेंचमार्किंग का प्रयास करें ।
फील

2

खाली रेगेक्स

किसी भी चीज़ से कभी भी मेल न खाने वाला सबसे अच्छा रेगेक्स एक खाली रेगेक्स है। लेकिन मुझे यकीन नहीं है कि सभी रेगेक्स इंजन इसे स्वीकार करेंगे।

असंभव रीगेक्स

अन्य उपाय एक असंभव regex बनाना है। मैंने पाया कि $-^आपके पाठ के आकार ( https://regex101.com/r/yjcs1Z/1 ) की परवाह किए बिना गणना करने के लिए केवल दो कदम हैं ।

सन्दर्भ के लिए:

  • $^और $.गणना करने के लिए 36 कदम उठाए -> O (1)
  • \b\B मेरे नमूने पर 1507 कदम उठाता है और आपकी स्ट्रिंग के चरित्र की संख्या में वृद्धि करता है -> O (n)

इस सवाल के बारे में अधिक लोकप्रिय धागा:


1

शायद यह?

/$.+^/

पायथन में, यह दृष्टिकोण केवल तभी काम करता है जब आप झंडे को नियंत्रित करते हैं : re.compile('$.+^', re.MULTILINE|re.DOTALL).search('a\nb\nc\n')बी और सी के अनुरूप एक मैच ऑब्जेक्ट लौटाता है (और सभी आसन्न और नए के बीच)। नकारात्मक-लुकहेड दृष्टिकोण मैं काम की सिफारिश करता हूं (यानी, कुछ भी मेल करने में विफल रहता है) झंडे के किसी भी संयोजन के लिए इसे संकलित किया जा सकता है।
एलेक्स मार्टेली

मेरा बुरा - मिश्रित $और ^
क्रिस लुत्ज

1
यह शुरुआत से पहले एक स्ट्रिंग के अंत की तलाश करने का प्रयास हो सकता है , लेकिन मैंने पाया है कि $ का मतलब 'स्ट्रिंग का अंत' नहीं है जब तक कि यह रेगेक्स का अंतिम चरित्र नहीं है, और मुझे उम्मीद है कि एक समान व्यवहार लागू होता है ^, तो यह एक शाब्दिक $ के साथ शुरू होने वाले एक विकल्प से मेल खा सकता है, और एक शाब्दिक के साथ समाप्त हो सकता है ^
पैविअम

@pavium, यह निश्चित रूप से पायथन या जावास्क्रिप्ट में उस तरह का व्यवहार नहीं करता है। जब तक आप उन्हें \ "के साथ नहीं छोड़ते या उन्हें [] के साथ सेट चरित्र में शामिल नहीं करते हैं, तब तक $ और ^ जैसे विशेष वर्णों को शाब्दिक नहीं माना जाना चाहिए। आपने इसे किस भाषा में देखा?
पीटर हैनसेन

पर्ल में, कम से कम, यह लिखा जाना चाहिए /\z.+\A/(देखें perldoc perlre ) जो मल्टी-लाइन और सिंगल-लाइन मोड ( use re '/ms') को प्रभावित करने से रोकता है।
ब्रैड गिल्बर्ट

0
'[^0-9a-zA-Z...]*'

और सभी मुद्रण योग्य प्रतीकों के साथ बदलें;)। यह एक पाठ फ़ाइल के लिए है।


मुझे लगता है कि इसके लिए एक छोटा रास्ता होना चाहिए, लेकिन यह मेरा पहला विचार भी था ^ ^
FP

4
यह खाली स्ट्रिंग से मेल खाएगा। हर संभव चरित्र को पकड़ने के [^\x00-\xFF]+लिए, बाइट-आधारित कार्यान्वयन के लिए उपयोग करें ।
फर्डिनेंड बायर

6
एक बेहतर अभिव्यक्ति होगी [^\s\S]। लेकिन जैसा कि फर्डिनेंड बेयर ने पहले ही कहा था, यह एक खाली स्ट्रिंग से मेल खाएगा।
Gumbo

3
Drakosha की regex की वजह से एक रिक्त स्ट्रिंग से मेल खा सकता है *; उस बंद को छोड़ दें, या इसे बदल दें +, और इसे कम से कम एक वर्ण से मेल खाना चाहिए। यदि वर्ग सभी संभावित वर्णों को बाहर कर देता है, तो यह कुछ भी मेल नहीं खा सकता है।
एलन मूर

0

रेगेक्स के बारे में क्या है, बस अगर बयान में हमेशा झूठ का उपयोग करें? जावास्क्रिप्ट में:

var willAlwaysFalse=false;
if(willAlwaysFalse)
{
}
else
{
}

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

-2

एक पोर्टेबल समाधान जो रेगेक्सपी कार्यान्वयन पर निर्भर नहीं होगा, बस एक निरंतर स्ट्रिंग का उपयोग करना है जो आपको यकीन है कि लॉग संदेशों में कभी नहीं दिखाई देगा। उदाहरण के लिए निम्नलिखित के आधार पर एक स्ट्रिंग बनाएं:

cat /dev/urandom | hexdump | head -20
0000000 5d5d 3607 40d8 d7ab ce72 aae1 4eb3 ae47
0000010 c5e2 b9e8 910d a2d9 2eb3 fdff 6301 c85f
0000020 35d4 c282 e439 33d8 1c73 ca78 1e4d a569
0000030 8aca eb3c cbe4 aff7 d079 ca38 8831 15a5
0000040 818b 323f 0b02 caec f17f 387b 3995 88da
0000050 7b02 c80b 2d42 8087 9758 f56f b71f 0053
0000060 1501 35c9 0965 2c6e 03fe 7c6d f0ca e547
0000070 aba0 d5b6 c1d9 9bb2 fcd1 5ec7 ee9d 9963
0000080 6f0a 2c91 39c2 3587 c060 faa7 4ea4 1efd
0000090 6738 1a4c 3037 ed28 f62f 20fa 3d57 3cc0
00000a0 34f0 4bc2 3067 a1f7 9a87 086b 2876 1072
00000b0 d9e1 6b8f 5432 a60e f0f5 00b5 d9ef ed6f
00000c0 4a85 70ee 5ec4 a378 7786 927f f126 2ec2
00000d0 18c5 46fe b167 1ae6 c87c 1497 48c9 3c09
00000e0 8d09 e945 13ce 7da2 08af 1a96 c24c c022
00000f0 b051 98b3 2bf5 4d7d 5ec4 e016 a50d 355b
0000100 0e89 d9dd b153 9f0e 9a42 a51f 2d46 2435
0000110 ef35 17c2 d2aa 3cc7 e2c3 e711 d229 f108
0000120 324e 5d6a 650a d151 bc55 963f 41d3 66ee
0000130 1d8c 1fb1 1137 29b2 abf7 3af7 51fe 3cf4

यकीन है, यह एक बौद्धिक चुनौती नहीं है, लेकिन डक्ट टेप प्रोग्रामिंग की तरह ।


-6
new Regex(Guid.NewGuid().ToString())

केवल अल्फ़ान्यूमेरिक्स और ' -' (जिनमें से कोई भी विशेष वर्ण हैं) में से एक पैटर्न बनाता है, लेकिन यह उसी स्ट्रिंग के लिए सांख्यिकीय रूप से असंभव है जो पहले कहीं भी दिखाई दिया हो (क्योंकि यह एक GUID का पूरा बिंदु है।)


2
"सांख्यिकीय रूप से असंभव"? है ना? GUID की गणना कैसे की जाती है, इसके आधार पर, अगले GUID की भविष्यवाणी करना संभव और अक्सर काफी सरल होता है (जैसा कि वे उन्हें और समय की गणना करने वाली मशीन पर निर्भर करते हैं)। आपका मतलब है "संभावनाहीन", "एक बहुत छोटी संभावना के साथ", लेकिन आप पूरी तरह से यादृच्छिक तारों के लिए भी "असंभव" नहीं कह सकते। आपका Regex तार की एक अनंत संख्या से मेल खाएगा - यह प्रश्न एक की तलाश में है जो कुछ भी मेल नहीं खाएगा। कभी।
फर्डिनेंड बेयर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.