2009-01-15 11 views
14

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

"foo.? bar*" 

"^.*foo\.\w\bar\w+.*" 

किसी तरह, मैं तो मैं ग्लोब को बदलने के लिए * जरूरत है और स्ट्रिंग से सभी सार्थक वर्ण से बचने के लिए की जरूरत है, करने के लिए परिवर्तित किया जाना चाहिए? अनुचित regexp वाक्यविन्यास के साथ अक्षर। ऐसा करने का सबसे अविश्वसनीय तरीका क्या है?

+0

regex एक सा लग रहा है अजीब। पसंद: "^। * Foo" को "foo" के रूप में लिखा जा सकता है। और मुझे लगता है कि ग्लोबिंग स्टार रेगेक्स "। *?" में अनुवाद करता है। खोज में जगह कहां गई? और \ बार "ar" से शुरू होने वाले शब्दों से मेल खाता है। – PEZ

उत्तर

-2

इस लिंक की कोशिश करो आवश्यकताओं को समझें। यदि मुझे लगता है कि उपयोगकर्ता टेक्स्ट "प्रविष्टियां" ढूंढना चाहते हैं जहां उनकी खोज मेल होती है तो मुझे लगता है कि यह क्रूर तरीका शुरुआत के रूप में काम करेगा।

सबसे पहले सब कुछ regex अर्थपूर्ण से बचें। फिर गैर-रेगेक्स प्रतिस्थापन का उपयोग करें (अब बच निकले) ग्लोब वर्णों को बदलने और नियमित अभिव्यक्ति का निर्माण करने के लिए। तो अजगर की तरह:

regexp = re.escape(search_string).replace(r'\?', '.').replace(r'\*', '.*?') 

प्रश्न में खोज स्ट्रिंग के लिए, यह एक regexp कि इतने (कच्चे) की तरह दिखता है बनाता है:

foo\..\ bar.*? 

एक अजगर स्निपेट में उपयोग किया:

search = "foo.? bar*" 
text1 = 'foo bar' 
text2 = 'gazonk foo.c bar.m m.bar' 

searcher = re.compile(re.escape(s).replace(r'\?', '.').replace(r'\*', '.*?')) 

for text in (text1, text2): 
    if searcher.search(text): 
    print 'Match: "%s"' % text 

का उत्पादन:

Match: "gazonk foo.c bar.m m.bar" 

ध्यान दें कि यदि आप मैच ऑब्जेक्ट की जांच करते हैं तो आप मैच के बारे में अधिक जानकारी प्राप्त कर सकते हैं और हाइलाइटिंग या जो कुछ भी कर सकते हैं।

बेशक, इसके लिए और भी कुछ हो सकता है, लेकिन यह एक शुरुआत होनी चाहिए।

+15

बस एक उत्तर के रूप में एक लिंक पोस्ट करना एक अच्छा जवाब नहीं है। यदि भविष्य में लिंक टूट जाता है तो क्या होगा? आपको अपने उत्तर में लिंक उद्धृत करने के लिए प्रोत्साहित किया जाता है, ताकि अगर लिंक टूट जाए, तो जवाब स्टैक ओवरफ़्लो पर अभी भी मौजूद है। –

1

मैं अपने खुद के समारोह लिखने ++ और बढ़ावा देने :: regex

std::string glob_to_regex(std::string val) 
{ 
    boost::trim(val); 
    const char* expression = "(\\*)|(\\?)|([[:blank:]])|(\\.|\\+|\\^|\\$|\\[|\\]|\\(|\\)|\\{|\\}|\\\\)"; 
    const char* format = "(?1\\\\w+)(?2\\.)(?3\\\\s*)(?4\\\\$&)"; 
    std::stringstream final; 
    final << "^.*"; 
    std::ostream_iterator<char, char> oi(final); 
    boost::regex re; 
    re.assign(expression); 
    boost::regex_replace(oi, val.begin(), val.end(), re, format, boost::match_default | boost::format_all); 
    final << ".*" << std::ends; 
    return final.str(); 
} 

यह लग रहा है सब की तरह ठीक काम करता है

2

मैं पूरी तरह से मैं सुनिश्चित नहीं हूं:

+0

सही है, लेकिन आपको alsough प्रतिस्थापन() | \ [] और serarch string – Lazin

+0

में अन्य सार्थक वर्णों की आवश्यकता है, इसे इंगित करने के लिए धन्यवाद। अब तय – PEZ

43

अपूर्ण या अविश्वसनीय हैक्स की कोई आवश्यकता नहीं है। वहाँ इस

>>> import fnmatch 
>>> fnmatch.translate('*.foo') 
'.*\\.foo$' 
>>> fnmatch.translate('[a-z]*.txt') 
'[a-z].*\\.txt$' 
1

jPaq के RegExp.fromWildExp समारोह के लिए एक समारोह अजगर के साथ शामिल है इस के लिए कुछ ऐसा ही। निम्न उदाहरण साइट के मुख पृष्ठ पर है कि से लिया जाता है:

// Find a first substring that starts with a capital "C" and ends with a 
// lower case "n". 
alert("Where in the world is Carmen Sandiego?".findPattern("C*n")); 

// Finds two words (first name and last name), flips their order, and places 
// a comma between them. 
alert("Christopher West".replacePattern("(<*>) (<*>)", "p", "$2, $1")); 

// Finds the first number that is at least three numbers long. 
alert("2 to the 64th is 18446744073709551616.".findPattern("#{3,}", "ol"));