2012-02-24 10 views
5

की तुलना करने के लिए नियमित अभिव्यक्तियों का उपयोग करना तो यह "आप इसे गलत कर रहे हैं" का एक स्पष्ट मामला है। मैं वास्तव में ऐसा करने का इरादा नहीं रखता हूं, लेकिन काम पर एक वार्तालाप ने इस सवाल को प्रेरित किया:संख्या

क्या आप यह निर्धारित करने के लिए एक नियमित अभिव्यक्ति उत्पन्न कर सकते हैं कि एक पूर्णांक मनमाना मूल्य से कम है या नहीं।

कुछ मूल्यों के लिए यह आसान है। 1000 से कम पूर्णांक के लिए, \ d {1,3} चाल चलनी चाहिए। पूर्णांक < 500 के लिए, यह थोड़ा सा कठिन है, लेकिन बुरा नहीं है, क्योंकि आप [0-4] {0,1} \ d {1,2} का उपयोग कर सकते हैं।

एक बार जब आप मनमाना मूल्य प्राप्त कर लेते हैं तो यह बहुत अधिक चालक हो जाता है। उदाहरण के लिए, 255 से कम की सभी संख्याएं \ d {1,2} | जैसी कुछ होंगी [0-1] \ डी {2} | [2] [0-4] \ डी | [2] [5] [0-4]।

क्या कोई नियमित नियमित अभिव्यक्ति है जो यहां काम करती है? या क्या आपको प्रोग्रामिक रूप से रेगेक्स उत्पन्न करना है?

(और फिर, मुझे कहना है कि मैं वास्तव में ऐसा करने का कोई इरादा नहीं है। जाहिर है अपने पसंदीदा प्रोग्रामिंग भाषा में उपयोग करते हुए "foo < बार" चलो कहीं अधिक कुशल और आसान को पढ़ने के लिए है।)

+0

आप तीन भाव आप एक ही एक प्राप्त करने के लिए जोड़ सकता है कि अगर तुम क्या मतलब है। – Dervall

उत्तर

3

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

+0

हू? क्या आप कह रहे हैं कि यह नहीं किया जा सकता है, या यह हाँ कहने का एक मजेदार तरीका है? क्या आप नकारात्मक संख्याओं की ओर इशारा करते हैं, भले ही ओपी स्पष्ट रूप से गैर-ऋणात्मक संख्या स्थान को लागू कर रहा हो? – tripleee

+0

नहीं किया जा सकता है। आप एक regexp नहीं लिख सकते हैं जो सामान्य रूप से आपको बताएगा कि क्या मनमाना संख्या मनमानी सीमा से अधिक है, क्योंकि वे सीमित नहीं हैं। –

+0

यदि ओपी का मतलब सिर्फ एक विशेष संख्या है, तो वह इसे छोटे से कर सकता है - उसके बाध्यता के नीचे सभी मूल्यों को समेकित करें। फिर यदि वह महत्वाकांक्षी महसूस कर रहा है, तो संबंधित एफएसएम को कम करें और न्यूनतम रेगेक्स का उपयोग करें। –

2

यह काफी आसान है।

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Regexp::Assemble; 

for my $n (@ARGV) { 
    my $asm = new Regexp::Assemble; 
    for (1 .. $n) { $asm->add($_) } 
    for ($asm->re){ 
     s/\)$/\$/; 
     s/^[^:]*:/^/; 
     print "$n => /$_/\n"; 
    } 
} 

अब पैटर्न है कि 1 के बीच पूर्णांकों से मेल खाता है और उस नंबर को खोजने के लिए इसे चलाने:

$ perl /tmp/ra 5 15 153 401 1144 
5 => /^[12345]$/ 
15 => /^(?:[23456789]|1[]?)$/ 
153 => /^(?:1(?:[6789]|5[0123]?|0\d?|1\d?|2\d?|3\d?|4\d?)?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)$/ 
401 => /^(?:1(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|2(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|3(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|4(?:[123456789]|0[01]?)?|5\d?|6\d?|7\d?|8\d?|9\d?)$/ 
1144 => /^(?:1(?:0(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|1(?:[56789]|4[]?|0\d?|1\d?|2\d?|3\d?)?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|2(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|3(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|4(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|5(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|6(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|7(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|8(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?|9(?:0\d?|1\d?|2\d?|3\d?|4\d?|5\d?|6\d?|7\d?|8\d?|9\d?)?)$/