रेगेक्स को बनाए रखना
पूर्व में "नियमित अभिव्यक्ति" के रूप में संदर्भित पैटर्न को ध्वस्त करने की दिशा में एक प्रमुख अग्रिम है पर्ल का /xरेग्ज फ्लैग - कभी-कभी (?x)जब एम्बेडेड लिखा जाता है - जो व्हाट्सएप (लाइन ब्रेकिंग, इंडेंटिंग) और टिप्पणियों की अनुमति देता है। यह गंभीरता से पठनीयता और इसलिए रखरखाव में सुधार करता है। सफेद स्थान संज्ञानात्मक चैंकिंग के लिए अनुमति देता है, इसलिए आप देख सकते हैं कि किस समूह के साथ क्या है।
आधुनिक पैटर्न भी अब अपेक्षाकृत गिने और नामित बैकरेफरेंस का समर्थन करते हैं। इसका मतलब है कि आपको अब कैप्चर समूहों की गणना करने की आवश्यकता नहीं है जो आपको चाहिए $4या \7। यह पैटर्न बनाते समय मदद करता है जिसे आगे के पैटर्न में शामिल किया जा सकता है।
यहाँ एक उदाहरण है एक अपेक्षाकृत संख्या में कब्जा समूह:
$ डुपोर्ट = qr {\ b (?: (\ w +)) (?: \ s + \ g {-1}) +) \ b} xi;
$ उद्धृत = qr {([""] $ डुपोर्ट \ 1} x;
और यहाँ नामित कब्जा के बेहतर दृष्टिकोण का एक उदाहरण है:
$dupword = qr{ \b (?: (?<word> \w+ ) (?: \s+ \k<word> )+ ) \b }xi;
$quoted = qr{ (?<quote> ["'] ) $dupword \g{quote} }x;
व्याकरणिक संदर्भ
सबसे अच्छा , इन नामित कैप्चर को एक (?(DEFINE)...)ब्लॉक के भीतर रखा जा सकता है , ताकि आप अपने पैटर्न के अलग-अलग नामित तत्वों के निष्पादन से घोषणा को अलग कर सकें। यह उन्हें पैटर्न के भीतर सबरूटीन की तरह कार्य करता है।
इस तरह के "व्याकरणिक रेगेक्स" का एक अच्छा उदाहरण इस उत्तर और इस एक में पाया जा सकता है । ये व्याकरण संबंधी घोषणा के समान हैं।
जैसा कि उत्तरार्द्ध आपको याद दिलाता है:
... सुनिश्चित करें कि पंक्ति ‐ शोर पैटर्न कभी न लिखें। आपके पास नहीं है, और आपको नहीं करना चाहिए। किसी भी प्रोग्रामिंग भाषा को बनाए नहीं रखा जा सकता है जो सफेद स्थान, टिप्पणियों, सबरूटीन्स या अल्फ़ान्यूमेरिक पहचानकर्ताओं को मना करता है। इसलिए अपने पैटर्न में उन सभी चीजों का उपयोग करें।
यह अधिक जोर नहीं दिया जा सकता है। बेशक अगर आप अपने पैटर्न में उन चीजों का उपयोग नहीं करते हैं, तो आप अक्सर दुःस्वप्न पैदा करेंगे। लेकिन अगर आप कर उन्हें इस्तेमाल, हालांकि, आप नहीं आवश्यकता नहीं है।
आधुनिक व्याकरणिक पैटर्न का एक और उदाहरण, RFC 5322 को पार्स करने के लिए यह एक है: 5.10.0 का उपयोग करें;
$rfc5322 = qr{
(?(DEFINE)
(?<address> (?&mailbox) | (?&group))
(?<mailbox> (?&name_addr) | (?&addr_spec))
(?<name_addr> (?&display_name)? (?&angle_addr))
(?<angle_addr> (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
(?<group> (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ; (?&CFWS)?)
(?<display_name> (?&phrase))
(?<mailbox_list> (?&mailbox) (?: , (?&mailbox))*)
(?<addr_spec> (?&local_part) \@ (?&domain))
(?<local_part> (?&dot_atom) | (?"ed_string))
(?<domain> (?&dot_atom) | (?&domain_literal))
(?<domain_literal> (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
\] (?&CFWS)?)
(?<dcontent> (?&dtext) | (?"ed_pair))
(?<dtext> (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])
(?<atext> (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
(?<atom> (?&CFWS)? (?&atext)+ (?&CFWS)?)
(?<dot_atom> (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
(?<dot_atom_text> (?&atext)+ (?: \. (?&atext)+)*)
(?<text> [\x01-\x09\x0b\x0c\x0e-\x7f])
(?<quoted_pair> \\ (?&text))
(?<qtext> (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
(?<qcontent> (?&qtext) | (?"ed_pair))
(?<quoted_string> (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
(?&FWS)? (?&DQUOTE) (?&CFWS)?)
(?<word> (?&atom) | (?"ed_string))
(?<phrase> (?&word)+)
# Folding white space
(?<FWS> (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
(?<ctext> (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
(?<ccontent> (?&ctext) | (?"ed_pair) | (?&comment))
(?<comment> \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
(?<CFWS> (?: (?&FWS)? (?&comment))*
(?: (?:(?&FWS)? (?&comment)) | (?&FWS)))
# No whitespace control
(?<NO_WS_CTL> [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])
(?<ALPHA> [A-Za-z])
(?<DIGIT> [0-9])
(?<CRLF> \x0d \x0a)
(?<DQUOTE> ")
(?<WSP> [\x20\x09])
)
(?&address)
}x;
यह उल्लेखनीय नहीं है - और शानदार? आप एक बीएनएफ-शैली व्याकरण ले सकते हैं और अपनी मौलिक संरचना को खोए बिना सीधे कोड में अनुवाद कर सकते हैं!
यदि आधुनिक व्याकरणिक पैटर्न अभी भी आपके लिए पर्याप्त नहीं हैं, तो डेमियन कॉनवे के शानदार Regexp::Grammarsमॉड्यूल बेहतर डीबगिंग के साथ एक समान क्लीनर सिंटैक्स भी प्रदान करता है। यहाँ RFC 5322 को उस मॉड्यूल से एक पैटर्न में पार्स करने के लिए समान कोड है:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Data::Dumper "Dumper";
my $rfc5322 = do {
use Regexp::Grammars; # ...the magic is lexically scoped
qr{
# Keep the big stick handy, just in case...
# <debug:on>
# Match this...
<address>
# As defined by these...
<token: address> <mailbox> | <group>
<token: mailbox> <name_addr> | <addr_spec>
<token: name_addr> <display_name>? <angle_addr>
<token: angle_addr> <CFWS>? \< <addr_spec> \> <CFWS>?
<token: group> <display_name> : (?:<mailbox_list> | <CFWS>)? ; <CFWS>?
<token: display_name> <phrase>
<token: mailbox_list> <[mailbox]> ** (,)
<token: addr_spec> <local_part> \@ <domain>
<token: local_part> <dot_atom> | <quoted_string>
<token: domain> <dot_atom> | <domain_literal>
<token: domain_literal> <CFWS>? \[ (?: <FWS>? <[dcontent]>)* <FWS>?
<token: dcontent> <dtext> | <quoted_pair>
<token: dtext> <.NO_WS_CTL> | [\x21-\x5a\x5e-\x7e]
<token: atext> <.ALPHA> | <.DIGIT> | [!#\$%&'*+-/=?^_`{|}~]
<token: atom> <.CFWS>? <.atext>+ <.CFWS>?
<token: dot_atom> <.CFWS>? <.dot_atom_text> <.CFWS>?
<token: dot_atom> <.CFWS>? <.dot_atom_text> <.CFWS>?
<token: dot_atom_text> <.atext>+ (?: \. <.atext>+)*
<token: text> [\x01-\x09\x0b\x0c\x0e-\x7f]
<token: quoted_pair> \\ <.text>
<token: qtext> <.NO_WS_CTL> | [\x21\x23-\x5b\x5d-\x7e]
<token: qcontent> <.qtext> | <.quoted_pair>
<token: quoted_string> <.CFWS>? <.DQUOTE> (?:<.FWS>? <.qcontent>)*
<.FWS>? <.DQUOTE> <.CFWS>?
<token: word> <.atom> | <.quoted_string>
<token: phrase> <.word>+
# Folding white space
<token: FWS> (?: <.WSP>* <.CRLF>)? <.WSP>+
<token: ctext> <.NO_WS_CTL> | [\x21-\x27\x2a-\x5b\x5d-\x7e]
<token: ccontent> <.ctext> | <.quoted_pair> | <.comment>
<token: comment> \( (?: <.FWS>? <.ccontent>)* <.FWS>? \)
<token: CFWS> (?: <.FWS>? <.comment>)*
(?: (?:<.FWS>? <.comment>) | <.FWS>)
# No whitespace control
<token: NO_WS_CTL> [\x01-\x08\x0b\x0c\x0e-\x1f\x7f]
<token: ALPHA> [A-Za-z]
<token: DIGIT> [0-9]
<token: CRLF> \x0d \x0a
<token: DQUOTE> "
<token: WSP> [\x20\x09]
}x;
};
while (my $input = <>) {
if ($input =~ $rfc5322) {
say Dumper \%/; # ...the parse tree of any successful match
# appears in this punctuation variable
}
}
वहाँ में अच्छी चीजें की एक बहुत कुछ है perlre मैनपेज , लेकिन मौलिक regex डिजाइन सुविधाओं में इन नाटकीय सुधार किसी भी तरह अकेले पर्ल तक ही सीमित द्वारा कर रहे हैं। वास्तव में pcrepattern मैनपेज एक आसान पढ़ा जा सकता है, और एक ही क्षेत्र को कवर करता है।
आधुनिक पैटर्न में लगभग कुछ भी सामान्य नहीं है जो आपको अपने परिमित ऑटोमेटा वर्ग में सिखाया गया था।