यह कैसे जांचें कि एक स्ट्रिंग नियमित अभिव्यक्ति का उपयोग करके एक पैलिंड्रोम है?


93

यह एक साक्षात्कार प्रश्न था जिसका मैं उत्तर देने में असमर्थ था:

यह कैसे जांचें कि एक स्ट्रिंग नियमित अभिव्यक्ति का उपयोग करके एक पैलिंड्रोम है?

ps पहले से ही एक सवाल है कि " कैसे जांचा जाए कि दिए गए तार पैलिंड्रोम हैं? "


1
stackoverflow.com/questions/3644266/… एक विचार दे सकते हैं।
प्रखर

2
आजकल (2018) के लिए और जो "palindrome regex" की तलाश कर रहा है , Prakhar के लिंक पर PCRE का समर्थन करने वाले पुनरावर्ती पैटर्न और नीचे मेरे पुनरावर्ती regex के बारे में चर्चा देखें, तुलना के साथ
पीटर क्रूस

जवाबों:


151

इस सवाल का जवाब है कि "यह असंभव है"। विशेष रूप से, साक्षात्कारकर्ता सोच रहा है कि क्या आपने अपने कम्प्यूटेशनल सिद्धांत वर्ग में ध्यान दिया।

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

एक नियमित अभिव्यक्ति को हमेशा एक समरूप परिमित अवस्था मशीन में अनुवादित किया जा सकता है। यही है, एक जो नियमित अभिव्यक्ति के रूप में एक ही शब्द को स्वीकार करता है और खारिज करता है (वास्तविक दुनिया में, कुछ regexp भाषाएं मनमाने कार्यों के लिए अनुमति देती हैं, ये गिनती नहीं होती हैं)।

एक परिमित राज्य मशीन का निर्माण करना असंभव है जो सभी पैलिंड्रोम्स को स्वीकार करता है। प्रमाण उन तथ्यों पर निर्भर करता है जो हम आसानी से एक स्ट्रिंग का निर्माण कर सकते हैं जिसके लिए मनमाने ढंग से बड़ी संख्या में नोड्स की आवश्यकता होती है, अर्थात स्ट्रिंग

ए ^ xba ^ x (जैसे।, अबा, अनाबा, आआआआआआआब, आआआआआआआआबबबा, ....)

जहाँ ^ x एक दोहराया जाने वाला x बार है। इसके लिए कम से कम x नोड्स की आवश्यकता होती है, क्योंकि 'b' को देखने के बाद हमें यह सुनिश्चित करने के लिए x x को वापस गिनना होगा कि यह एक palindrome है।

अंत में, मूल प्रश्न पर वापस जा रहे हैं, आप साक्षात्कारकर्ता को बता सकते हैं कि आप एक नियमित अभिव्यक्ति लिख सकते हैं जो सभी पैलिंड्रोम्स को स्वीकार करता है जो कुछ परिमित निश्चित लंबाई से छोटे होते हैं। यदि कभी कोई वास्तविक दुनिया का अनुप्रयोग होता है जिसे पैलिंड्रोमों की पहचान करने की आवश्यकता होती है, तो यह लगभग निश्चित रूप से मनमाने ढंग से लंबे लोगों को शामिल नहीं करेगा, इस प्रकार यह उत्तर दिखाएगा कि आप वास्तविक-दुनिया के अनुप्रयोगों से सैद्धांतिक अशुद्धियों को अलग कर सकते हैं। फिर भी, वास्तविक regexp काफी लंबा होगा, समकक्ष 4-लाइन प्रोग्राम (पाठक के लिए आसान अभ्यास: palindromes को पहचानने वाला प्रोग्राम लिखें) की तुलना में बहुत लंबा है।


6
@SteveMoser रूबी 1.9.x में, रेग्युलर एक्सप्रेशंस अब रेगुलर (ऑटोमैटिक थ्योरी सेन्स में) रेगुलर नहीं हैं और इस तरह से palindromes के लिए जाँच करना संभव है। हालांकि, इरादों और उद्देश्यों के लिए, palindromes को रेग्युलर रेगेक्स (मतलब नहीं?) के साथ चेक नहीं किया जा सकता है ।

1
@SteveMoser रूबी के रेगुलर एक्सप्रेशन इंजन ( >=1.9) का अच्छा

@ जॉन सही है, इसलिए सवाल के संदर्भ में जोस सही है और हक गलत है।
स्टीव मोजर

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

एक मौखिक परीक्षण में zou shoulsd "formalz यह असंभव है" के साथ चलते हैं, लेकिन आपको यह इंगित करना चाहिए कि कुछ रेगेक्स इसे अनुमति देते हैं।
ओलिवर ए।

46

जबकि PCRE इंजन पुनरावर्ती नियमित अभिव्यक्तियों का समर्थन करता है ( पीटर क्रस द्वारा उत्तर देखें ), आप अतिरिक्त कोड के बिना इसे प्राप्त करने के लिए ICU इंजन (उदाहरण के लिए, Apple द्वारा) का उपयोग नहीं कर सकते । आपको ऐसा कुछ करने की आवश्यकता होगी:

यह किसी भी तालमेल का पता लगाता है, लेकिन एक लूप की आवश्यकता होती है (जिसकी आवश्यकता होगी क्योंकि नियमित अभिव्यक्ति की गणना नहीं की जा सकती है)।

$a = "teststring";
while(length $a > 1)
{
   $a =~ /(.)(.*)(.)/;
   die "Not a palindrome: $a" unless $1 eq $3;
   $a = $2;
}
print "Palindrome";

4
अच्छा उत्तर। प्रश्न ने एक एकल regexp के लिए नहीं पूछा जो सीधे बॉक्स से बाहर एक palindrome का पता लगाता है - यह केवल palindromes का पता लगाने की एक विधि के लिए पूछा है जो regexps का उपयोग करता है। इस तरह से देखने के लिए आपकी अंतर्दृष्टि पर बधाई।
स्टीवर्ट

1
यह भी देखें सबसे सरल मिलान (स्ट्रिंग परिवर्तन के बिना) केवल एक regex, का उपयोग कर stackoverflow.com/a/48608623/287948
पीटर क्रूस

धन्यवाद @PeterKrauss नहीं पता था कि पीसीआरई में पुनरावृत्ति थी। आपके उत्तर को संदर्भित करता है।
एयरसोर्स लिमिटेड

32

यह मुमकिन नहीं है। Palindromes को एक नियमित भाषा द्वारा परिभाषित नहीं किया जाता है। (देखें, I DID कम्प्यूटेशनल सिद्धांत में कुछ सीखते हैं)


2
अधिकांश नियमित अभिव्यक्ति इंजन नियमित भाषाओं से अधिक कैप्चर करते हैं (नेट उदाहरण के लिए मिलान कोष्ठक पर कब्जा कर सकते हैं)। केवल मानक रेगीक्स नियमित लैंग्स तक सीमित हैं।
सैंटियागो प्लादिनो

प्रश्न ने "नियमित अभिव्यक्ति" शब्द का उपयोग किया था, हालांकि ... ZCHudson का उत्तर सही है।
paxos1977

2
@austirg: ZCHudson का उत्तर सही है लेकिन अधूरा है। आधुनिक प्रोग्रामिंग भाषाओं में उपयोग किए जाने वाले नियमित भाव और सैद्धांतिक सीएस कक्षाओं में उपयोग किए जाने वाले नियमित भाव अलग-अलग जानवर हैं। यह शब्द सिर्फ एक ऐतिहासिक धरोहर है। Stackoverflow.com/questions/233243#235199 और मेरा उत्तर देखें ।
jfs

2
@ जेएफ सेबेस्टियन - मुझे इस पर ऑस्ट्रिर्ग से सहमत होना होगा। जब शब्द की नियमित अभिव्यक्ति का उपयोग विशिष्ट प्रोग्रामिंग भाषा के बिना किया जाता है, जो कि कंपेन डिफिनिशन लागू होता है, से उल्लेखित है। रेगेक्स का समर्थन करने वाली सभी भाषाएँ ऐसा नहीं कर सकती हैं, इसलिए हमें यह नहीं मान लेना चाहिए कि यहाँ जो प्रयोग किया गया है।
२३:११ पर रोनटोलॉजिस्ट

@ चिकित्सक: मुझे इस सवाल पर प्रोग्रामिंग भाषा की पसंद पर कोई प्रतिबंध नहीं है, इस प्रकार किसी भी भाषा की अनुमति है। दाईं ओर देखें: संबंधित प्रश्नों में "नियमित अभिव्यक्ति" का क्या अर्थ है? क्या उनमें से किसी में विशिष्ट प्रोग्रामिंग भाषा का उल्लेख किया जा रहा है?
दोपहर

27

पर्ल रेगेक्स के साथ:

/^((.)(?1)\2|.?)$/

हालांकि, जैसा कि कई ने बताया है, अगर आप सख्त होना चाहते हैं तो इसे एक नियमित अभिव्यक्ति नहीं माना जा सकता है। नियमित अभिव्यक्तियाँ पुनरावृत्ति का समर्थन नहीं करती हैं।



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

1
आश्चर्यजनक रूप से, गैर-लैटिन भाषाओं के लिए काम नहीं करता है, उदाहरण के लिए अर्मेनियाई भाषा।
तेमुजिन

3
@Temujin यह या तो है, क्योंकि यूनिकोड वर्ण एन्कोड बाइट के रूप में मिलान किया जाता है (जोड़ने /uसंशोधक , या क्योंकि Combinator पात्रों में से)। ( भागने के क्रम से प्रतिस्थापित .करें )। \X
मार्कस जार्डेरोट

1
पीसीआरई में मेरा पैटर्न काम नहीं करता है। यह पर्ल में काम करता है। जब सबस्ट्रिंग दोहराया जाता है तो आपका पैटर्न फेल हो जाता है। उदाहरण के लिए abababa। पीसीआर-आधारित रेगेक्स इंजन का उपयोग करते समय हर इनपुट के लिए पुनरावृत्ति के साथ काम करना संभव नहीं है। Casimirs regex पुनरावृत्ति और परिवर्तनशील स्थिति का उपयोग करते हुए एक अलग दृष्टिकोण का उपयोग करता है, और काफी आकर्षक है।
मार्कस जार्डेरोट

15

यहां किसी भी प्रकार के चरित्र के लिए 4-अक्षर पलिंड्रोम्स (जैसे: विलेख) का पता लगाने के लिए एक है:

\(.\)\(.\)\2\1

यहां 5-अक्षर वाले palindromes (जैसे: रडार) का पता लगाने के लिए एक है, केवल पत्रों के लिए जाँच:

\([a-z]\)\([a-z]\)[a-z]\2\1

तो ऐसा लगता है कि हमें प्रत्येक संभावित शब्द लंबाई के लिए एक अलग रेगेक्स की आवश्यकता है। पायथन मेलिंग सूची की इस पोस्ट में क्यों (परिमित राज्य ऑटोमेटा और पम्पिंग लेम्मा) के रूप में कुछ विवरण शामिल हैं।


14

आप कितने आश्वस्त हैं, इस पर निर्भर करते हुए, मैं यह जवाब देता हूं:

मैं इसे एक नियमित अभिव्यक्ति के साथ नहीं करूंगा। यह नियमित अभिव्यक्ति का उपयुक्त उपयोग नहीं है।


3
मुझे उम्मीद है कि आप थोड़ा और स्पष्टीकरण देंगे, यह दिखाने के लिए कि आप वास्तव में रेगेक्स की सीमाओं को समझते हैं। आपका सरल उत्तर "मैं स्टम्प्ड हूं" के रूप में लिया जा सकता है।
स्कॉट वेगनर

इसलिए निर्भर निर्भरता उसने दी।
विल बर्कफोर्ड

13

हाँ , आप इसे .Net में कर सकते हैं!

(?<N>.)+.?(?<-N>\k<N>)+(?(N)(?!))

आप इसे यहाँ देख सकते हैं ! यह एक अद्भुत पोस्ट है!


.NET फ्लेक्स रेगेक्स की पूरी बात यह है कि वे नियमित नहीं हैं क्योंकि वे एक परिमित राज्य ऑटोमेटा नहीं हैं; वे वास्तव में सैद्धांतिक अर्थ में regex नहीं हैं।
बिल्ली

12

StackOverflow जवाब की तरह भरा है "नियमित अभिव्यक्ति? नहीं, वे इसका समर्थन नहीं करते। वे नहीं कर सकते समर्थन ।"

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

यहाँ पेरी के निर्माता लैरी वॉल का एक उद्धरण है:

(…) आम तौर पर जिसे हम “रेगुलर एक्सप्रेशन” कहते हैं, के साथ क्या करना है, जो केवल वास्तविक रेगुलर एक्सप्रेशंस से थोड़े संबंधित हैं। फिर भी, शब्द हमारे पैटर्न मिलान इंजन की क्षमताओं के साथ विकसित हुआ है, इसलिए मैं यहां भाषाई आवश्यकता से लड़ने की कोशिश नहीं कर रहा हूं। हालाँकि, मैं आम तौर पर उन्हें "रेगेक्स" (या "रेगेक्सेन" कहता हूं, जब मैं एक एंग्लो-सैक्सन मूड में हूं)।

और यहाँ PHP के मुख्य डेवलपर्स में से एक ब्लॉग पोस्ट है :

जैसा कि लेख काफी लंबा था, यहाँ मुख्य बिंदुओं का सारांश है:

  • औपचारिक भाषा सिद्धांत के संदर्भ में नियमितताओं की मूल धारणा के साथ प्रोग्रामर द्वारा उपयोग किए जाने वाले "नियमित अभिव्यक्ति" बहुत कम हैं।
  • नियमित अभिव्यक्ति (कम से कम पीसीआरई) सभी संदर्भ-मुक्त भाषाओं से मेल खा सकती है। जैसे कि वे अच्छी तरह से बनाई गई HTML और अन्य सभी प्रोग्रामिंग भाषाओं से बहुत मेल खा सकते हैं।
  • नियमित अभिव्यक्ति कम से कम कुछ संदर्भ-संवेदनशील भाषाओं से मेल खा सकती है।
  • नियमित अभिव्यक्तियों का मिलान एनपी-पूर्ण है। जैसे कि आप नियमित अभिव्यक्ति का उपयोग करके किसी अन्य एनपी समस्या को हल कर सकते हैं।

कहा जा रहा है, आप इस का उपयोग करके रेगेक्स के साथ पैलिन्ड्रोम का मिलान कर सकते हैं:

^(?'letter'[a-z])+[a-z]?(?:\k'letter'(?'-letter'))+(?(letter)(?!))$

... जिसका स्पष्ट रूप से नियमित व्याकरण से कोई लेना-देना नहीं है।
यहाँ अधिक जानकारी: http : //www . अनियमित-expressions.info/balancing.html


9

जैसा कि कुछ पहले ही कह चुके हैं, कोई एकल regexp नहीं है जो बॉक्स से बाहर एक सामान्य ताल का पता लगाएगा, लेकिन यदि आप एक निश्चित लंबाई तक के palindromes का पता लगाना चाहते हैं, तो आप कुछ का उपयोग कर सकते हैं

(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1

7

यह अब पर्ल में किया जा सकता है। पुनरावर्ती संदर्भ का उपयोग करना:

if($istr =~ /^((\w)(?1)\g{-1}|\w?)$/){
    print $istr," is palindrome\n";
}

निकटवर्ती अंतिम भाग http://perldoc.perl.org/perlretut.html पर आधारित है


6

रूबी में आप नामित कैप्चर समूहों का उपयोग कर सकते हैं। तो कुछ इस तरह काम करेगा -

def palindrome?(string)
  $1 if string =~ /\A(?<p>| \w | (?: (?<l>\w) \g<p> \k<l+0> ))\z/x
end

कोशिश करो, यह काम करता है ...

1.9.2p290 :017 > palindrome?("racecar")
 => "racecar" 
1.9.2p290 :018 > palindrome?("kayak")
 => "kayak" 
1.9.2p290 :019 > palindrome?("woahitworks!")
 => nil 

1
नामित कैप्चर समूह सख्ती से रेगेक्स नहीं हैं। willamette.edu/~fruehr/LLC/lab5.html
स्टीव मोजर

2
तुम सही हो। Thats विशेष रूप से क्यों मैंने बताया कि आपको कैप्चर समूहों के नाम का उपयोग करना होगा।
टेलर

किसी को किसी भी मौका द्वारा समझा सकता है कि आरई चरित्र एक नौसिखिया के लिए? मैं निम्न में से सभी को समझता हूं (अल्पविराम से 'परमाणु' अलग हो जाते हैं), / ए, (;, (।, \ w,;), (, (,, \ w,),),), z, /, x, लेकिन मैं डॉन 'इनमें से किसी को भी नहीं समझे? <p>;;?; <l>, \ g <p>, \ k <l + 0> और मैं मदद के लिए rubular.com का उपयोग कर रहा हूँ और यह RE ( स्वाभाविक रूप से), लेकिन यह मुझे इसे देखने में मदद नहीं करता है, और यहां तक ​​कि "एक पूर्ण रूबी रेगेक्स गाइड के लिए, पिकैक्स देखें।" मदद नहीं करता है, 'पिकैक्स' से जुड़ी साइट के लिए उन परमाणुओं की व्याख्या नहीं करता है जिन्हें मैं समझने में विफल रहा हूं। मुझे पता है ? शून्य या एक में से एक मैच का आयोजन, लेकिन? एक चरित्र से पहले?
केविन फोर्ड ने सबमरीन

आह, नाम पर कब्जा समूहों ! अच्छा लगा। @SteveMoser अब एक टूटी हुई कड़ी है, लेकिन मुझे एक और मिला । धन्यवाद उनका उल्लेख करने के लिए टेलर, अन्यथा, मुझे नहीं पता था कि इसका क्या मतलब था? <P> और? <L> और?: (गैर-कैप्चरिंग ग्रुप) और \ g <p> और \ k <l +? 0>। मैं अब भी नहीं देख पा रहा हूं? <P> | हालांकि है। नहीं करता है | मतलब "या"? मैं आरईएस में पाइप के लिए उस उपयोग के दस्तावेज खोजने में असमर्थ हूं। मैं अभी भी यह बहुत अच्छा आरई के लिए एक विस्तृत विवरण देखने के लिए खुश हो जाएगा।
केविन फोर्ड ने सबमरीन

5

यह वास्तव में नियमित अभिव्यक्तियों के बजाय स्ट्रिंग हेरफेर के साथ करना आसान है:

bool isPalindrome(String s1)

{

    String s2 = s1.reverse;

    return s2 == s1;
}

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


जबकि मैं इस उत्तर का काफी शौकीन हूं, मुझे लगता है कि आप दृश्य वर्णों को स्ट्रिंग को ठीक से विभाजित करने के लिए ब्रेकइंटरेटर का उपयोग करके अतिरिक्त अंक प्राप्त करेंगे।
तर्जुक

5

रेगेक्स गोल्फ के 5 वें स्तर (एक आदमी, एक योजना) पर मेरा जवाब है । यह ब्राउज़र के Regexp के साथ 7 वर्णों तक काम करता है (मैं Chrome 36.0.1985.143 का उपयोग कर रहा हूं)।

^(.)(.)(?:(.).?\3?)?\2\1$

यहाँ 9 वर्णों के लिए एक है

^(.)(.)(?:(.)(?:(.).?\4?)?\3?)?\2\1$

अधिकतम उन वर्णों की संख्या बढ़ाने के लिए, जिन्हें आप बार-बार बदलना चाहते हैं ? के साथ (?: (?)? \ n?)


1
मैंने उस एक को थोड़े कम वर्णों के साथ प्रबंधित किया, ^ ((।) (।)?;? \ 3 \ 2 \ 1 $
बेन एलिस

इसे मुझे खराब करने के लिए बहुत बहुत धन्यवाद :-)
U10- फॉरवर्ड

बाकी लोगों के पास 13 क्यों हैं, लेकिन यह 19 है
U10- फॉरवर्ड

5

पुनरावर्ती नियमित भाव यह कर सकते हैं!

एक स्ट्रिंग का पता लगाने के लिए इतना सरल और स्व-स्पष्ट एल्गोरिथम:

   (\w)(?:(?R)|\w?)\1

पर rexegg.com/regex-recursion ट्यूटोरियल बताते हैं कि यह कैसे काम करता है।


यह किसी भी भाषा के साथ ठीक काम करता है, यहाँ एक उदाहरण उसी स्रोत (लिंक) से जो कि PHP का उपयोग करते हुए प्रूफ-ऑफ-कॉन्सेप्ट के रूप में अनुकूलित है:

$subjects=['dont','o','oo','kook','book','paper','kayak','okonoko','aaaaa','bbbb'];
$pattern='/(\w)(?:(?R)|\w?)\1/';
foreach ($subjects as $sub) {
  echo $sub." ".str_repeat('-',15-strlen($sub))."-> ";
  if (preg_match($pattern,$sub,$m)) 
      echo $m[0].(($m[0]==$sub)? "! a palindrome!\n": "\n");
  else 
      echo "sorry, no match\n";
}

आउटपुट

dont ------------> sorry, no match
o ---------------> sorry, no match
oo --------------> oo! a palindrome!
kook ------------> kook! a palindrome!
book ------------> oo
paper -----------> pap
kayak -----------> kayak! a palindrome!
okonoko ---------> okonoko! a palindrome!
aaaaa -----------> aaaaa! a palindrome!
bbbb ------------> bbb

की तुलना

नियमित अभिव्यक्ति ^((\w)(?:(?1)|\w?)\2)$ एक ही काम करती है, लेकिन हां "नहीं" के बजाय।
पुनश्च: यह एक परिभाषा का उपयोग कर रहा है जहां "ओ" एक पैलिम्ब्रोम नहीं है, "सक्षम-एल्बा" ​​हाइफ़न प्रारूप एक पैलिंड्रोम नहीं है, लेकिन "सक्षम" है। इसका नामकरण किया परिभाषा १
जब "ओ" और "सक्षम-एल्बा" ​​पलिंड्रोन्स होते हैं, जिसका नामकरण परिभाषा 2 है

एक और "पैलिंड्रोम रेगेक्स" की तुलना में,

  • ^((.)(?:(?1)|.?)\2)$ आधार-रेगेक्स बिना ऊपर \w प्रतिबंध के , "सक्षम-एल्बा" ​​को स्वीकार करते हुए।

  • ^((.)(?1)?\2|.)$( @LilDevil ) परिभाषा 2 का प्रयोग करें ("ओ" और "सक्षम- " को स्वीकार करते हैं, इसलिए "आआआआ" और "बब्ब" स्ट्रिंग्स की मान्यता में भी भिन्नता है)।

  • ^((.)(?1)\2|.?)$( @ मर्कस ) का पता नहीं "कूक" और न ही "बीबीबीबी"

  • ^((.)(?1)*\2|.?)$( @Caba ) परिभाषा 2 का प्रयोग करें ।


नोट: तुलना करने के लिए आप $subjectsप्रत्येक रेगेक्स की तुलना में अधिक शब्द और एक पंक्ति जोड़ सकते हैं ,

  if (preg_match('/^((.)(?:(?1)|.?)\2)$/',$sub)) echo " ...reg_base($sub)!\n";
  if (preg_match('/^((.)(?1)?\2|.)$/',$sub)) echo " ...reg2($sub)!\n";
  if (preg_match('/^((.)(?1)\2|.?)$/',$sub)) echo " ...reg3($sub)!\n";
  if (preg_match('/^((.)(?1)*\2|.?)$/',$sub)) echo " ...reg4($sub)!\n";

5

आप इसे पुनरावृत्ति का उपयोग किए बिना भी कर सकते हैं:

\A(?:(.)(?=.*?((?(2)\1\2|\1))\z))*?.?\2\z

किसी एकल वर्ण को अनुमति देने के लिए:

\A(?:(?:(.)(?=.*?((?(2)\1\2|\1))\z))*?.?\2|.)\z

पर्ल, पीसीआरई के साथ काम करता है

डेमो

जावा के लिए:

\A(?:(.)(?=.*?(\1\2\z|(?<!(?=\2\z).{0,1000})\1\z)))*?.?\2\z

डेमो


1
यह एक रेगेक्स प्रश्न का बहुत ही रोचक उत्तर है। वास्तव में एकमात्र पैटर्न, जिसने मेरे कुछ परीक्षणों को पारित किया । इस एक कासिमिर के लिए धन्यवाद :)
बबलबल बबल

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

4

पीसीआरई अभिव्यक्ति के बारे में (छिपकली से):

/^((.)(?1)\2|.?)$/

क्या आपने इसका परीक्षण किया है? विन XP प्रो के तहत मेरे PHP 5.3 पर यह विफल रहता है: आबा वास्तव में, मैंने पढ़ने के लिए अभिव्यक्ति की अभिव्यक्ति को थोड़ा संशोधित किया:

/^((.)(?1)*\2|.?)$/

मुझे लगता है कि यह क्या हो रहा है, जबकि पात्रों की बाहरी जोड़ी लंगर डाले हुए है, शेष आंतरिक नहीं हैं। यह पूरी तरह से उत्तर नहीं है क्योंकि यह गलत तरीके से "आबा" और "अनाबाका" पर गुजरता है, यह "औराबा" पर सही ढंग से विफल होता है।

मुझे आश्चर्य है कि क्या इसके लिए एक तय है, और क्या, पर्ल उदाहरण (JF सेबेस्टियन / Zsolt द्वारा) मेरे परीक्षणों को सही ढंग से पास करता है?

वियना से सेबा गाबोर




2

जैसा कि ZCHudson द्वारा बताया गया है , यह निर्धारित करें कि क्या कुछ है एक palindrome एक सामान्य regexp के साथ नहीं किया जा सकता है, क्योंकि palindrome का सेट एक नियमित भाषा नहीं है।

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



2

मैं साक्षात्कारकर्ता को समझाऊंगा कि पालिंद्रोम्स से युक्त भाषा एक नियमित भाषा नहीं है, बल्कि संदर्भ-मुक्त है।

नियमित अभिव्यक्ति जो सभी पैलिन्ड्रोम से मेल खाती है अनंत होगी । इसके बजाय मैं सुझाव दूंगा कि वह स्वीकार करने के लिए खुद को या तो अधिकतम आकार तक सीमित कर ले; या यदि सभी palindromes को कम से कम किसी प्रकार के NDPA के उपयोग की आवश्यकता होती है, या बस साधारण स्ट्रिंग रिवर्सल / बराबर तकनीक का उपयोग करते हैं।


2

कब्जा समूहों से बाहर निकलने से पहले आप सबसे अच्छे से रेगेक्स कर सकते हैं:

/(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?)(.?).?\9\8\7\6\5\4\3\2\1/

यह लंबाई में सभी 19 वर्णों तक मेल खाएगा।

सभी लंबाई के लिए प्रोग्रामेटिक हल करना तुच्छ है:

str == str.reverse ? true : false

आपका रेगेक्स काम नहीं करता है। उदाहरण के लिए, यह इंगित करेगा कि "अबेक" एक मैच है ...
डार्विन

2

मेरे पास इनलाइन पर टिप्पणी करने के लिए रिपीट नहीं है, लेकिन McamX द्वारा प्रदान की गई रेगेक्स, और सेसाबा द्वारा संशोधित, इसे पीसीआरई में काम करने के लिए और भी संशोधित किया जा सकता है। एकमात्र विफलता जो मुझे मिली है वह सिंगल-चार स्ट्रिंग है, लेकिन मैं इसके लिए अलग से परीक्षण कर सकता हूं।

/^((.)(?1)?\2|.)$/

यदि आप इसे किसी अन्य स्ट्रिंग्स पर विफल कर सकते हैं, तो कृपया टिप्पणी करें।


2
#!/usr/bin/perl

use strict;
use warnings;

print "Enter your string: ";
chop(my $a = scalar(<STDIN>));    
my $m = (length($a)+1)/2;
if( (length($a) % 2 != 0 ) or length($a) > 1 ) { 
  my $r; 
  foreach (0 ..($m - 2)){
    $r .= "(.)";
  }
  $r .= ".?";
  foreach ( my $i = ($m-1); $i > 0; $i-- ) { 
    $r .= "\\$i";
  } 
  if ( $a =~ /(.)(.).\2\1/ ){
    print "$a is a palindrome\n";
  }
  else {
    print "$a not a palindrome\n";
 }
exit(1);
}
print "$a not a palindrome\n";

2

ऑटोमेटा सिद्धांत से इसकी असंभवता किसी भी लंबन के पिलियनड्रोम से मेल खाती है (क्योंकि इसमें अनंत मात्रा में स्मृति की आवश्यकता होती है)। लेकिन यह निश्चित लंबाई के Paliandromes से मेल करने के लिए POSSIBLE है। एक ऐसा रेगेक्स लिखना संभव है जो लंबाई के सभी पिलियनड्रोमों से मेल खाता हो <= 5 या <= 6 आदि, लेकिन नहीं> = 5 आदि जहां ऊपरी सीमा अस्पष्ट है।


2

रूबी में आप \b(?'word'(?'letter'[a-z])\g'word'\k'letter+0'|[a-z])\bpalindrome शब्दों से मिलान करने के लिए उपयोग कर सकते हैं जैसे a, dad, radar, racecar, and redivider। पीएस: यह रेग्ज केवल पैलिंड्रोम शब्दों से मेल खाता है जो विषम संख्या में अक्षर हैं।

आइए देखें कि यह रेगेक्स रडार से कैसे मेल खाता है। स्ट्रिंग की शुरुआत में शब्द सीमा \ b मेल खाता है। रेगेक्स इंजन कैप्चरिंग ग्रुप "वर्ड" में प्रवेश करता है। [az] r से मेल खाता है जो फिर से रिक्रिएशन लेवल जीरो पर कैप्चरिंग ग्रुप "लेटर" के लिए स्टैक में स्टोर होता है। अब रेगेक्स इंजन समूह "शब्द" की पहली पुनरावृत्ति में प्रवेश करता है। ((? 'अक्षर' [az]) मैच और एक स्तर पर कब्जा कर लेता है। रेगेक्स समूह "शब्द" की दूसरी पुनरावृत्ति में प्रवेश करता है। (? 'अक्षर' [az]) पुनरावर्ती स्तर दो पर d को दर्शाता है। अगले दो पुनरावर्ती के दौरान, समूह ए और आर को तीन और चार के स्तर पर कब्जा कर लेता है। पांचवी पुनरावृत्ति विफल हो जाती है क्योंकि मैच के लिए [az] स्ट्रिंग में कोई वर्ण नहीं बचा है। रेगेक्स इंजन को पीछे करना चाहिए।

रेगेक्स इंजन को अब समूह "शब्द" के अंदर दूसरे विकल्प की कोशिश करनी चाहिए। रेगेक्स में दूसरा [az] स्ट्रिंग में अंतिम आर से मेल खाता है। इंजन अब एक सफल पुनर्संरचना से बाहर निकलता है, एक स्तर पर तीसरी पुनरावर्तन तक जाता है।

मिलान (और शब्द) के बाद इंजन \ k'letter + 0 'तक पहुंचता है। बैकरेक्शन विफल हो जाता है क्योंकि रेगेक्स इंजन पहले ही विषय स्ट्रिंग के अंत तक पहुंच गया है। तो यह एक बार फिर से पीछे हट जाता है। दूसरा विकल्प अब a से मेल खाता है। रेगेक्स इंजन तीसरी पुनरावृत्ति से बाहर निकलता है।

रेगेक्स इंजन फिर से (और शब्द) से मेल खा गया है और इसे फिर से पीछे हटने का प्रयास करने की आवश्यकता है। Backreference +0 या पुनरावृत्ति के वर्तमान स्तर को निर्दिष्ट करता है, जो 2 है। इस स्तर पर, कैप्चरिंग समूह d से मेल खाता है। Backreference विफल हो जाता है क्योंकि स्ट्रिंग में अगला वर्ण r है। पीछे फिर से, दूसरा वैकल्पिक मैच डी।

अब, \ k'letter + 0 'स्ट्रिंग में दूसरे से मेल खाता है। ऐसा इसलिए है क्योंकि रेगेक्स इंजन पहले पुनरावृत्ति पर वापस आ गया है, जिसके दौरान कैप्चरिंग समूह पहले ए से मेल खाता है। रेगेक्स इंजन पहली पुनरावृत्ति से बाहर निकलता है।

रेगेक्स इंजन अब सभी रिकर्सन के बाहर वापस आ गया है। यह स्तर, कैप्चरिंग समूह संग्रहीत आर। Backreference अब स्ट्रिंग में अंतिम आर का मिलान कर सकता है। चूंकि इंजन किसी भी अधिक पुनरावृत्ति के अंदर नहीं है, यह समूह के बाद रेगेक्स के शेष के साथ आगे बढ़ता है। \ n स्ट्रिंग के अंत में मेल खाता है। रेगेक्स का अंत तक पहुँच गया है और रडार को समग्र मैच के रूप में लौटाया गया है।


2

यहां पीएल / एसक्यूएल कोड है जो बताता है कि दिया गया स्ट्रिंग पैलिंड्रोम है या नियमित अभिव्यक्ति का उपयोग नहीं कर रहा है:

create or replace procedure palin_test(palin in varchar2) is
 tmp varchar2(100);
 i number := 0;
 BEGIN
 tmp := palin;
 for i in 1 .. length(palin)/2 loop
  if length(tmp) > 1 then  
    if regexp_like(tmp,'^(^.).*(\1)$') = true then 
      tmp := substr(palin,i+1,length(tmp)-2);
    else 
      dbms_output.put_line('not a palindrome');
      exit;
    end if;
  end if;  
  if i >= length(palin)/2 then 
   dbms_output.put_line('Yes ! it is a palindrome');
  end if;
 end loop;  
end palin_test;

2
my $pal='malayalam';

while($pal=~/((.)(.*)\2)/){                                 #checking palindrome word
    $pal=$3;
}
if ($pal=~/^.?$/i){                                         #matches single letter or no letter
    print"palindrome\n";
}
else{
    print"not palindrome\n";
}

2
हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन यह समस्या का हल कैसे और / या इसके बारे में अतिरिक्त संदर्भ प्रदान करता है, इससे उत्तर के दीर्घकालिक मूल्य में सुधार होगा।
डोनाल्ड डक

2

यह रेगेक्स रिक्त स्थान, टैब, अल्पविराम और उद्धरणों को अनदेखा करते हुए 22 वर्णों तक के तालमेल का पता लगाएगा।

\b(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*(?:(\w)[ \t,'"]*\11?[ \t,'"]*\10|\10?)[ \t,'"]*\9|\9?)[ \t,'"]*\8|\8?)[ \t,'"]*\7|\7?)[ \t,'"]*\6|\6?)[ \t,'"]*\5|\5?)[ \t,'"]*\4|\4?)[ \t,'"]*\3|\3?)[ \t,'"]*\2|\2?))?[ \t,'"]*\1\b

इसके साथ यहां खेलें: https://regexr.com/4tmui


0

एयरसोर्स लिमिटेड की विधि का एक मामूली शोधन, स्यूडोकोड में:

WHILE string.length > 1
    IF /(.)(.*)\1/ matches string
        string = \2
    ELSE
        REJECT
ACCEPT
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.