रेगेक्स बिल्कुल एन या एम बार


105

निम्नलिखित नियमित अभिव्यक्ति है, जहां पर विचार Xहै किसी भी regex।

X{n}|X{m}

यह रेगेक्स बिल्कुल या बार Xहोने के लिए परीक्षण करेगा । nm

क्या कोई रेगेक्स क्वांटिफायर है जो किसी घटना के लिए Xठीक n- ठीक या mकई बार परीक्षण कर सकता है?


सं दो की आवृत्तियां Xसबसे अच्छा आप सामान्य के लिए प्राप्त कर सकते हैं m, n
जॉन ड्वोरक

यदि यह मेरी समस्या थी, तो मैं रेगेक्स बैकरेफर का प्रयास करूंगा और इसके साथ शुरू करूंगा (X)\1{n-1}(?:\1{m-n-1})। मुझे पता है कि यह मैच Xकम से कम एक बार होता है, लेकिन बस शुरू करने के लिए इस सरल चीज़ को आज़माएं और फिर इसके बजाय लुकहेड या लुकहाइंड का उपयोग करके परिष्कृत करें (X)
nalply

जवाबों:


91

एक भी मात्रा निर्धारित नहीं है, जिसका अर्थ है "बिल्कुल एम या एन बार"। जिस तरह से आप कर रहे हैं वह ठीक है।

एक विकल्प है:

X{m}(X{k})?

कहाँ m < nऔर kका मूल्य है n-m


67

यहां क्वांटिफायर की पूरी सूची (संदर्भ। http : //www . अनियमित-expressions.info/reference.html ):

  • ?, ??- 0 या 1 घटनाएँ ( ??आलसी है, ?लालची है)
  • *, *?- किसी भी संख्या में घटनाएँ
  • +, +?- कम से कम एक घटना
  • {n}- बिल्कुल nघटित होता है
  • {n,m}- nकरने के लिए mआवृत्तियां, समावेशी
  • {n,m}?- nकरने के लिए mआवृत्तियां, आलसी
  • {n,}, {n,}?- कम से कम nघटना

"बिल्कुल एन या एम" पाने के लिए, आपको दो बार मात्रात्मक रेगेक्स लिखना होगा, जब तक कि एम, एन विशेष न हों:

  • X{n,m} अगर m = n+1
  • (?:X{n}){1,2} अगर m = 2n
  • ...

1
क्यों ?:आवश्यक है अगर m = 2nउदाहरण में? मेरे लिए इसके बिना ठीक काम करने लगता है।
एर

7
@ अगर आप बाहर जाते हैं ?:, तो समूह एक कैप्चरिंग समूह बन जाता है। रेगेक्स इंजन के अलावा सामान को याद रखने की जरूरत नहीं है, अगर आपके पास इस एक के बाद समूहों को कैप्चर करना है, तो उनकी आईडी बदल जाएगी। यदि आप प्रतिस्थापन के लिए अपने रेगेक्स का उपयोग करते हैं, तो आपको प्रतिस्थापन को समायोजित करना होगा।
जॉन ड्वोरक

19

नहीं, ऐसा कोई क्वांटिफायर नहीं है। लेकिन मैं इसे रीस्ट्रक्चर करने में /X{m}(X{m-n})?/आने वाली समस्याओं को रोकने के लिए इसका पुनर्गठन करूंगा ।


3

TLDR; (?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)

लगता है कि आप "xn टाइम्स" या "xm टाइम्स" चाहते हैं, मुझे लगता है कि regex का शाब्दिक अनुवाद (x{n}|x{m}). इस तरह होगा https://regex101.com/r/vH7yL5/1

या, ऐसे मामले में जहाँ आपके पास m "x" s (मान m> n) से अधिक का अनुक्रम हो सकता है, तो आप 'no "x" का अनुसरण कर सकते हैं और' no "x" और उसके बाद अनुवाद कर सकते हैं, [^x](x{n}|x{m})[^x]लेकिन मान लें कि हमेशा "x" s के पीछे और उसके बाद एक चरित्र होता है। जैसा कि आप यहां देख सकते हैं: https://regex101.com/r/bB2vH2/1

आप इसे (?:[^x]|^)(x{n}|x{m})(?:[^x]|$)"निम्नलिखित में से कोई 'x' या निम्न पंक्ति प्रारंभ" और "उसके बाद कोई 'x' या उसके बाद पंक्ति के अंत में बदल सकते हैं।" लेकिन फिर भी, यह उनके बीच केवल एक ही चरित्र के साथ दो दृश्यों का मेल नहीं खाएगा (क्योंकि पहले मैच के बाद एक चरित्र की आवश्यकता होगी, और दूसरे चरित्र से पहले) जैसा कि आप यहां देख सकते हैं: https://regex101.com/r/ oC5oJ4 / 1

अंत में, एक वर्ण के दूर के मिलान के लिए, आप "के बाद" (=) पर एक सकारात्मक रूप जोड़ सकते हैं "या" से पहले "नहीं 'x पर" (<=) के पीछे एक सकारात्मक रूप "? इस तरह: https://regex101.com/r/mC4uX3/1

(?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)

इस तरह से आप केवल 'x' की इच्छित संख्या से मेल खाएँगे।


1

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

(?:[^x]|\b)(x{n}|x{m})(?:[^x]|\b)

जैसा कि आप देख सकते हैं: https://regex101.com/r/oC5oJ4/2


1
कूल, मैं इस बात से परिचित नहीं था कि रेगेक्स ने सीमाओं को कैसे संभाला। इस पद्धति के साथ एकमात्र समस्या तब है जब आप एक गैर-मानक सीमा का उपयोग कर रहे हैं। एक नज़र खींचें : regex101.com/r/j0nkeo/1 और regex101.com/r/4Ix7Dr/1
बढ़े हुए

1
@ भारित - यह एक अच्छा बिंदु है, कई मिलान समूहों के साथ एक मुद्दा प्रतीत होता है जो ओवरलैप होते हैं। यह एक ऐसी स्थिति है जहाँ आपको पीछे देखने की आवश्यकता होगी।
रोज़ज़ा 2058

1

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

#[a-f0-9]{6}|#[a-f0-9]{3}

यह हेक्स कलर कोड की सभी घटनाओं को खोजेगा (वे या तो 3 या 6 अंक लंबे हैं)। लेकिन जब मैं इसे इस तरह से चारों ओर फ्लिप करता हूं

#[a-f0-9]{3}|#[a-f0-9]{6}

इसमें केवल 3 अंक वाले या 6 अंकों वाले पहले 3 अंक मिलेंगे। यह समझ में आता है और एक रेगेक्स समर्थक इसे तुरंत हाजिर कर सकता है, लेकिन कई लोगों के लिए यह एक अजीब व्यवहार हो सकता है। कुछ उन्नत रेगेक्स विशेषताएं हैं जो आदेश की परवाह किए बिना इस जाल से बच सकते हैं, लेकिन हर कोई रेगेक्स पैटर्न में घुटने से गहरा नहीं है।

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