2010-08-09 7 views
13

मैं एक अजगर समारोह है कि एक नियमित रूप से अभिव्यक्ति का एक सादे अंग्रेजी विवरण लेने के लिए और फोन करने वाले के लिए नियमित अभिव्यक्ति लौट सकते हैं बनाने के लिए कोशिश कर रहा हूँ।क्या नियमित अभिव्यक्तियों को व्यक्त करने के एक और घोषणात्मक तरीके की आवश्यकता है? :)

वर्तमान में मैं YAML प्रारूप में वर्णन की सोच रहा हूँ। तो, हम विवरण को कच्चे स्ट्रिंग वेरिएबल के रूप में संग्रहीत कर सकते हैं, जो इस दूसरे फ़ंक्शन पर पास हो जाता है और उस फ़ंक्शन के आउटपुट को फिर 'री' मॉड्यूल में भेज दिया जाता है। के बाद एक नहीं बल्कि साधारण उदाहरण है:

# a(b|c)d+e* 
re1 = """ 
- literal: 'a' 
- one_of: 'b,c' 
- one_or_more_of: 'd' 
- zero_or_more_of: 'e' 
""" 
myre = re.compile(getRegex(re1)) 
myre.search(...) 

आदि

किसी को लगता है कि करता है इस तरह की कुछ व्यापक उपयोग की हो सकता है? क्या आप पहले से ही मौजूदा पैकेज जानते हैं जो इसे कर सकते हैं? इस दृष्टिकोण के लिए आप क्या सीमाएं देखते हैं? क्या कोई सोचता है कि कोड में घोषणात्मक स्ट्रिंग होने से, यह अधिक रखरखाव कर देगा?

+0

JSON या XML शायद? डीटीडी या एक्सएसडी भी एक डेटा संरचना अच्छी तरह से लिख सकते हैं। – codymanix

+7

तो एक जटिल एक पूरी लाइन ले जा regex के बजाय, यह एक पूरे पृष्ठ :) –

+4

जो लोग नियमित अभिव्यक्ति पता है कि यह साथ सहज हैं लगेगा, लेकिन जैसे वर्णमाला ऊपर फेंक दिया हर किसी को यह लग रहा है। यह एक मुद्दा हो सकता है, लेकिन मुझे यकीन नहीं है। आखिरकार, आप उन लोगों के लिए प्रोग्रामिंग भाषाओं की एक ही बात कह सकते हैं जो कार्यक्रम बनाम लोग हैं जो नहीं करते हैं। यह साथ वस्तुओं और कार्यों तार के instad यह करने के लिए अच्छा हो सकता है, लेकिन मुझे यकीन है कि क्या सबसे अच्छा तरीका लागू करने के लिए है कि हो सकता है नहीं कर रहा हूँ। नवाचार के लिए +1 सभी एक ही। – psicopoo

उत्तर

2

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

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

तुम भी वैकल्पिक तरीकों बातों को व्यक्त करने के बारे में सोच सकते हैं। उदाहरण के लिए, मेरे सामने हुआ पहला विचार लघु, याद रखने वाले नामों के साथ कार्यों का उपयोग करके रेगेक्स व्यक्त करना था। उदाहरण के लिए:

from refunc import * 

pattern = Compile(
    'a', 
    Capture(
     Choices('b', 'c'), 
     N_of('d', 1, Infin()), 
     N_of('e', 0, Infin()), 
    ), 
    Look_ahead('foo'), 
) 

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

pattern = Compile(
    'a', 
    Capture(
     '[bc]', 
     'd+', 
     'e*', 
    ), 
    Look_ahead('foo'), 
) 

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

6

यह वास्तव में सुंदर है कि कैसे एक lexer/पार्सर काम करता है के लिए इसी तरह (समान?) है। यदि आपके पास एक परिभाषित व्याकरण था तो आप शायद अधिक परेशानी के साथ एक पार्सर लिख सकते हैं। उदाहरण के लिए, आप इस तरह कुछ लिख सकते हैं:

<expression> :: == <rule> | <rule> <expression> | <rule> " followed by " <expression> 
<rule>  :: == <val> | <qty> <val> 
<qty>  :: == "literal" | "one" | "one of" | "one or more of" | "zero or more of" 
<val>  :: == "a" | "b" | "c" | "d" | ... | "Z" | 

यह एक सही वर्णन के पास कहीं भी नहीं है। अधिक जानकारी के लिए, this BNF of the regex language पर एक नज़र डालें। फिर आप lexing और parsing अभिव्यक्ति को देख सकते हैं।

आप इसे इस तरह से किया था, तो आप शायद एक छोटे से regexes के Natural Language/अंग्रेजी संस्करण के करीब हो सकता है।


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

बेशक यह बहुत लंबा पिक regex के लिए नहीं ले करता है के रूप में वाक्य रचना आमतौर पर संक्षिप्त है और अर्थ के सबसे सुंदर आत्म व्याख्यात्मक है, कम से कम अगर आप का उपयोग करें | या || आपकी भाषा में OR के रूप में, और आप 0-एन जोड़कर * 0-एन जोड़कर सोचते हैं।

हालांकि कभी कभी मैं टाइपिंग कोई फ़र्क नहीं पड़ेगा "एक या अधिक को खोजने के 'एक' तीन अंक या 'बी' फिर 'सी' के बाद"

+0

अपने 'एक regex लेने के लिए और errors.' पहचानना यह अंग्रेजी में बदल जाते हैं एक बहुत अधिक उपयोगी हो सकता है करने में सक्षम होने के नाते करने के लिए जवाब में की कोशिश प्रतिकृति मोड में पायथन के साथ 're.DEBUG' पैरामीटर। – Daenyth

+0

@Daenyth - मैं, कि मोड के बारे में पता कर रहा हूँ हालांकि मैं इसका इस्तेमाल करने के कारण नहीं गए थे, और मैं इसे मूल regex तुलना में काफी बेहतर है, जब तक यह एक बहुत ही जटिल regex है नहीं कह सकता। –

6

कृपया pyparsing पर एक नज़र डालें। आरई के साथ आप जिन मुद्दों का वर्णन करते हैं उनमें से कई वही हैं जो मुझे उस पैकेज को लिखने के लिए प्रेरित करते हैं।

O'Reilly ई-पुस्तक अध्याय "What's so special about pyparsing?" से पाइपर्सिंग की कुछ विशिष्ट विशेषताएं यहां दी गई हैं।

+1

आपने मुझे एक सेकंड से हराया! बीटीडब्ल्यू, लिखने के लिए धन्यवाद pyparsing :) –

2

आप के लिए हो सकता है कि वास्तव में क्या नहीं कह रहे हैं, लेकिन वहाँ एक रास्ता regexes अधिक पठनीय रास्ता लिखने के लिए कैसे (VERBOSE, शीघ्र ही X झंडा) है:

rex_name = re.compile(""" 
    [A-Za-z] # first letter 
    [a-z]+  # the rest 
""", re.X) 

rex_name.match('Joe') 
संबंधित मुद्दे