स्ट्रिंग के लिए रेगेक्स दिए गए प्रत्यय के साथ समाप्त नहीं होता है


188

मैं किसी भी स्थिति के साथ समाप्त नहीं होने वाले किसी भी स्ट्रिंग से मेल खाने के लिए एक उचित रेगेक्स नहीं ढूंढ सका हूं । उदाहरण के लिए, मैं एक के साथ समाप्त होने वाले कुछ भी मैच नहीं करना चाहता a

यह मेल खाता है

b
ab
1

यह मेल नहीं खाता

a
ba

मुझे पता है कि रेगेक्स को अंत $को चिह्नित करने के लिए समाप्त होना चाहिए , हालांकि मुझे नहीं पता कि इसे क्या करना चाहिए।

संपादित करें : मूल प्रश्न मेरे मामले के लिए एक कानूनी उदाहरण नहीं लगता है। तो: एक से अधिक पात्रों को कैसे संभालना है? कहो कुछ भी खत्म नहीं हो रहा है ab?

मैं इसे ठीक करने में सक्षम हूँ, इस धागे का उपयोग करके :

.*(?:(?!ab).).$

हालांकि इसके साथ नकारात्मक पक्ष यह है कि यह एक वर्ण के तार से मेल नहीं खाता है।


5
यह लिंक किए गए प्रश्न का डुप्लिकेट नहीं है - केवल अंत के खिलाफ मिलान करने के लिए एक स्ट्रिंग के भीतर कहीं भी मिलान करने की तुलना में एक अलग वाक्यविन्यास की आवश्यकता होती है। बस यहां शीर्ष उत्तर को देखें।
jaustin

मैं सहमत हूं, यह लिंक किए गए प्रश्न का डुप्लिकेट नहीं है। मुझे आश्चर्य है कि हम उपरोक्त "निशान" कैसे हटा सकते हैं?
एलन सबेरे

ऐसा कोई लिंक नहीं है जिसे मैं देख सकूं।
एलन कबरा

जवाबों:


249

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

.*(?<!a)$

(?<!a)यह सुनिश्चित करने के लिए एक नकारात्मक खोज है कि स्ट्रिंग के अंत से पहले (या mसंशोधक के साथ पंक्ति ), कोई चरित्र "ए" नहीं है।

Regexr पर इसे यहाँ देखें

आप इसे आसानी से अन्य वर्णों के साथ भी बढ़ा सकते हैं, क्योंकि यह स्ट्रिंग के लिए जाँच कर रहा है और वर्ण वर्ग नहीं है।

.*(?<!ab)$

यह ऐसी किसी भी चीज़ से मेल खाता होगा जो "ab" के साथ समाप्त नहीं होता है, इसे Regexr पर देखें


1
मैं RegexPAL नहीं जानता, लेकिन सभी भाषाओं में regexes अलग हैं और अभिकथन एक उन्नत विशेषता है जो सभी द्वारा समर्थित नहीं है।
Stema

7
regexpal एक जावास्क्रिप्ट आधारित regex परीक्षक है और javascript उन बातों का समर्थन नहीं करता है जो दुखद है
HamZa

रेबेक्स्र (जावास्क्रिप्ट) पर लुकबाइंड का समर्थन नहीं किया जाता है
चुपके रब्बी

1
जेएस में दिखावे की कमी मुझे रुलाती है। यदि आप सर्वर-साइड कर रहे हैं, तो आप शायद एनपीएम पर पीसीआरई मॉड्यूल का उपयोग कर सकते हैं या उन्हें सीधे उपयोग करने के लिए समान है (यह बाइंडिंग का एक सेट है, इसलिए मुझे नहीं लगता कि आप इसे फ्रंट-एंड का उपयोग कर सकते हैं)
एरिक बर्कलैंड

लुकहेड के अधिक प्रकार / दिखावे के दावे: stackoverflow.com/q/2973436/12484
जॉन श्नाइडर

76

नहीं ( ^) प्रतीक का प्रयोग करें :

.*[^a]$

यदि आप ^कोष्ठक की शुरुआत में प्रतीक रखते हैं, तो इसका अर्थ है "कोष्ठक में चीजों को छोड़कर सब कुछ।" $बस अंत तक एक लंगर है।

एकाधिक वर्णों के लिए , बस उन सभी को अपने वर्ण सेट में रखें:

.*[^a][^b]$

1
+1, इस चेतावनी के साथ कि यह खाली स्ट्रिंग से मेल नहीं खाता (जो कि जैसा हो सकता है या नहीं हो सकता है), इसलिए इसका अर्थ "कोई वर्ण जो कोष्ठक में नहीं है" है।
फ्रेड फू

3
@ 0A0D: एक स्ट्रिंग जिसमें व्हॉट्सऐप खाली स्ट्रिंग नहीं है।
फ्रेड फू

7
@ 0A0D दरअसल, यह बहस के लिए नहीं है, यह एक तथ्य है
tckmn

8
@ डॉर्कनोब: जो मेल नहीं खाता aeया cb
फ्रेड फू

1
नहीं, यह या तो "एसीबी" की अनुमति नहीं देगा।
मेनो

49

".Tmp" के साथ समाप्त न होने वाली फ़ाइलों की खोज करने के लिए हम निम्नलिखित regex का उपयोग करते हैं:

^(?!.*[.]tmp$).*$

रेगेक्स परीक्षक के साथ परीक्षण निम्नलिखित परिणाम देता है:

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


1
यह दिलचस्प है, किसी भी विचार क्यों यह काम करता है और क्यों ^.*(?![.]tmp$)नहीं करता है?
19:कसज़ ज़ारोदा

4
आपका प्रारंभिक .*पहले से ही पूरे स्ट्रिंग से मेल खाता है, इसलिए शेष बहिष्करण अब काम नहीं करता है।
पांचओ

मेरे उद्देश्यों के लिए, यह काम किया और अन्य जवाब नहीं दिया। धन्यवाद!
डेविड मोरित्ज़

8
.*[^a]$

ऊपर रेगेक्स स्ट्रिंग्स से मेल खाएगा जो खत्म नहीं हो रहा है a


मैंने अपना प्रश्न बढ़ाया है क्योंकि मूल उदाहरण पूरी तरह से मेरे मामले से मेल नहीं खाता है। क्या आप इसे हल कर सकते हैं?
मेनो

5

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

/.*[^a]$/

[]एक चरित्र वर्ग को दर्शाता है, और ^उलट चरित्र वर्ग सब कुछ है लेकिन एक मैच के लिए a


1

सवाल पुराना है, लेकिन मैं एक बेहतर समाधान नहीं ढूंढ सका जो मैं यहां पोस्ट करता हूं। सभी USB ड्राइव खोजें, लेकिन विभाजन को सूचीबद्ध नहीं करें , इस प्रकार परिणामों से "भाग [0-9]" को हटा दें। मैं दो grep कर रहा था, अंतिम परिणाम को नकारता है:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$"

मेरे सिस्टम पर यह परिणाम है:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

अगर मुझे केवल वे विभाजन चाहिए जो मैं कर सकता था:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$"

मुझे कहाँ मिलेगा:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1
pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2

और जब मैं करता हूं:

readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

मुझे मिला:

/dev/sdb

1

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

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

.*[^a]$

हम पाएंगे कि यह लगभग काम करता है। यह एक खाली स्ट्रिंग को स्वीकार नहीं करता है, जो थोड़ा अनिश्चित हो सकता है। हालांकि, यह केवल एक चरित्र के साथ काम करते समय एक मामूली मुद्दा है। हालाँकि, यदि हम पूरे स्ट्रिंग को बाहर करना चाहते हैं, उदाहरण के लिए "abc", तो:

.*[^a][^b][^c]$

नहीं करेंगे उदाहरण के लिए, यह एसी को स्वीकार नहीं करेगा।

हालांकि इस समस्या का एक आसान समाधान है। हम बस कह सकते हैं:

.{,2}$|.*[^a][^b][^c]$

या अधिक सामान्यीकृत संस्करण:

.{,n-1}$|.*[^firstchar][^secondchar]$ स्ट्रिंग आप न करे (के लिए चाहते हैं की लंबाई जहां n है abcयह 3 है), और firstchar, secondchar... पहले कर रहे हैं, अपने स्ट्रिंग के दूसरे ... वें वर्ण (के लिए abcयह होगा a, तो b, तो c)।

यह एक साधारण अवलोकन से आता है कि एक स्ट्रिंग जो पाठ की तुलना में कम है जिसे हम मना नहीं करेंगे परिभाषा में इस पाठ को शामिल नहीं किया जा सकता है। इसलिए हम या तो कुछ भी स्वीकार कर सकते हैं जो छोटा है ("ab" "abc" नहीं है), या हमें स्वीकार किए बिना कुछ भी काफी लंबा है, लेकिन अंत के बिना।

यहाँ एक उदाहरण है जो कि .jpg नहीं है सभी फ़ाइलों को हटा देगा:

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete


.{,2}$|.*[^a][^b][^c]$मेल नहीं खाताccc
psalaets

0

कुछ भी जो कुछ के साथ समाप्त होने वाली किसी भी चीज से मेल खाता है --- .*a$तो जब आप रेगेक्स से मेल खाते हैं, तो स्थिति को नकार दें या वैकल्पिक रूप से आप यह भी कर सकते हैं .*[^a]$कि [^a]इसका मतलब क्या हैnot a


0

यदि आप उपयोग कर रहे हैं grepया sedवाक्यविन्यास थोड़ा अलग होगा। ध्यान दें कि अनुक्रमिक [^a][^b]विधि यहाँ काम नहीं करती है:

balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n'
jd8a
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a]$"
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^b]$"
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^c]$"
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c]$"
jd8a
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c^a]$"

FWIW, मुझे Regex101 में वही परिणाम मिल रहे हैं , जो मुझे लगता है कि जावास्क्रिप्ट सिंटैक्स है।

खराब: https://regex101.com/r/MJGAmX/2
अच्छा: https://regex101.com/r/LzrIB1/2

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