2011-08-14 9 views
6

क्या रेगेक्स लिखने का कोई सुविधाजनक तरीका है जो regex जितना संभव हो उतना मिलान करने का प्रयास करेगा?क्या एक नियमित अभिव्यक्ति जितनी संभव हो सके मिलती रहती है?

उदाहरण:

my $re = qr/a ([a-z]+) (\d+)/; 

match_longest($re, "a") =>() 
match_longest($re, "a word") => ("word") 
match_longest($re, "a word 123") => ("word", "123") 
match_longest($re, "a 123") =>() 

है, $re नियमित अभिव्यक्ति का एक अनुक्रम माना जाता है यही कारण है, और match_longest प्रयास इस क्रम के रूप में ज्यादा मैच के लिए। एक मायने में, मिलान कभी विफल नहीं होता - यह केवल एक सवाल है कि कितना मिलान सफल हुआ। एक बार रेगेक्स मैच विफल हो जाता है, undef उन हिस्सों के लिए जो मेल नहीं खाते हैं।

मुझे पता है कि मैं एक समारोह लिख सकता हूं जो रेगेक्स का अनुक्रम लेता है और match_longest का काम करने के लिए एक एकल रेगेक्स बनाता है। यहां विचार की एक रूपरेखा दी गई है:

मान लें कि आपके पास तीन regexes हैं: $r1, $r2 और $r3

$r = ($r1 $r2 $r3)? | $r1 ($r2 $r3) | $r1 $r2 $r3? 

दुर्भाग्य से, इस regexes की संख्या में द्विघात है: match_longest का काम को करने के लिए एक regex निम्नलिखित संरचना होगा। क्या यह अधिक कुशल होना संभव है?

+0

'123' मैचों के बाद से उदाहरण regex बदल' \ w + ' – ErikR

उत्तर

5

आप regex

$r = ($r1 ($r2 ($r3)?)?)? 

जो प्रत्येक regex केवल एक बार निहित है उपयोग कर सकते हैं। आप अपने मूल नियमित अभिव्यक्तियों में हस्तक्षेप न करने के लिए इस उदाहरण में गैर-कैप्चरिंग समूह (?:...) का भी उपयोग कर सकते हैं।

+0

यह पीछे की जगह मौजूद होने पर केवल भागों को सही तरीके से कैप्चर करेगा। –

2

अगर मैं सवाल को समझते हैं, ? साथ नेस्टेड समूहों का उपयोग कर काम करना चाहिए:

my $re = qr/a ((\w+) (\d+)?)?/; 
+0

यह रेगेक्स पूरी तरह से 'शब्द' से मेल नहीं खाता है। –

0

इस विशेष मामले इस तरह लिखा जा सकता है:

m/a (?:(\w+)(?: (\d+))?)?/ 
संबंधित मुद्दे