रेगेक्स सत्यापन रेगेक्स [बंद]


17

एक regex बनाएँ जो इनपुट के रूप में एक regex स्ट्रिंग को स्वीकार करेगा और जाँच करेगा कि क्या यह वैध है। मूल रूप से, आपका रेगेक्स खुद को मान्य करने में सक्षम होना चाहिए। (किसी भी अमान्य रेगेक्स को मान्य नहीं किया जाना चाहिए, इसलिए आप उपयोग नहीं कर सकते हैं .*;))

आपके स्वाद को अच्छी तरह से ज्ञात कार्यान्वयन (पर्ल, सेड, ग्रीप, गॉक, आदि) द्वारा पूरी तरह से समर्थित होना चाहिए , और यह पूरी तरह से उन कार्यान्वयनों का समर्थन करना चाहिए। [वकील बोलने के बारे में चिंता न करें; मैं स्मार्ट के लिए किसी भी संभावित खामियों को दूर करने की कोशिश कर रहा हूं।


मैं इसे करूंगा, लेकिन मुझे चिंता है कि यह उन लोगों को बढ़त देगा जो गैर-सुविधा संपन्न स्वादों को जानते हैं और उनका उपयोग करते हैं। या मेरी चिंताएँ निराधार हैं?


8
संभव नहीं है, मनमाने ढंग से घोंसले के शिकार करने वाले ब्रैकेट एक रेगेक्स को एक संदर्भ मुक्त व्याकरण बनाते हैं, (इसे पॉलिश नोटेशन के साथ बदलना भी एक स्टैक की आवश्यकता है)
शाफ़्ट फ्रीक

@ शरत चेघ, आप सही कह सकते हैं।
मतीन उलहाक

1
नियमित भाषाओं पर कुछ एक्सटेंशन मौजूद हैं जो कोष्ठक से मेल खाने की अनुमति दे सकते हैं लेकिन मुझे नहीं पता कि यह कैसे करना है
शाफ़्ट फ्रीक

8
यह पर्ल रीगेक्स के साथ संभव हो सकता है।
पीटर टेलर

1
@BrianVandenberg आधुनिक भाषाओं में लागू होने वाले नियमित रूप से सभी गैर-नियमित बहुत अधिक हैं ... जैसे ही आप बैकरेफ़र जोड़ते हैं, आप गैर-नियमित भाषाओं से मेल खा सकते हैं। इसके अलावा, Perl / PCRE और .NET दोनों सही घोंसले के शिकार के लिए पर्याप्त शक्तिशाली हैं।
मार्टिन एंडर

जवाबों:


22

माणिक

मैंने जितना संभव हो सके रूबी के रेगेक्स स्वाद के वास्तविक सिंटैक्स से मिलान करने की कोशिश की, लेकिन कुछ क्विर्क हैं: यह कुछ लुकबाइंड को स्वीकार करता है जो वास्तव में अमान्य (जैसे (?<=(?<!))) हैं, और यह खाली वर्ण श्रेणियों को पहचानता है D-A। उत्तरार्द्ध ASCII के लिए तय किया जा सकता है, लेकिन रेगेक्स काफी लंबा है जैसा कि यह है।

\A(?<main>
    (?!
        \{(\d+)?,(\d+)?\} # do not match lone counted repetition
    )
    (?:
        [^()\[\]\\*+?|<'] | # anything but metacharacters
        (?<cclass>
            \[ \^? (?: # character class
                (?: # character class
                    [^\[\]\\-] | # anything but square brackets,  backslashes or dashes
                    \g<esc> |
                    \[ : \^? (?: # POSIX char-class
                        alnum | alpha | word | blank | cntrl | x?digit | graph | lower | print | punct | space | upper
                    ) : \] |
                    - (?!
                        \\[dwhsDWHS]
                    ) # range / dash not succeeded by a character class
                )+ |
                \g<cclass> # more than one bracket as delimiter
            ) \]
        ) |
        (?<esc>
            \\[^cuxkg] | # any escaped character
            \\x \h\h? | # hex escape
            \\u \h{4} | # Unicode escape
            \\c . # control escape
        ) |
        \\[kg] (?:
            < \w[^>]* (?: > | \Z) |
            ' \w[^']* (?: ' | \Z)
        )? | # named backrefs
        (?<! (?<! \\) \\[kg]) [<'] | # don't match < or ' if preceded by \k or \g
        \| (?! \g<rep> ) | # alternation
        \( (?: # group
            (?:
                \?
                (?:
                    [>:=!] | # atomic / non-capturing / lookahead
                    (?<namedg>
                        < [_a-zA-Z][^>]* > |
                        ' [_a-zA-Z][^']* ' # named group
                    ) |
                    [xmi-]+: # regex options
                )
            )?
            \g<main>*
        ) \) |
        \(\?<[!=] (?<lbpat>
            (?! \{(\d+)?,(\d+)?\} )
            [^()\[\]\\*+?] |
            \g<esc>  (?<! \\[zZ]) |
            \g<cclass> |
            \( (?: # group
                (?:
                    \?: |
                    \? \g<namedg> |
                    \? <[!=]
                )?
                \g<lbpat>*
            ) \) |
            \(\?\# [^)]* \)
        )* \)
        |
        \(\? [xmi-]+ \) # option group
        (?! \g<rep> ) 
        |
        \(\?\# [^)]*+ \) # comment
        (?! \g<rep> )
    )+
    (?<rep>
        (?:
            [*+?] | # repetition
            \{(\d+)?,(\d+)?\} # counted repetition
        )
        [+?]? # with a possessive/lazy modifier
    )?
)*\Z

अपठनीय संस्करण:

\A(?<main>(?!\{(\d+)?,(\d+)?\})(?:[^()\[\]\\*+?|<']|(?<cclass>\[\^?(?:(?:[^\[\]\\-]|\g<esc>|\[:\^?(?:alnum|alpha|word|blank|cntrl|x?digit|graph|lower|print|punct|space|upper):\]|-(?!\\[dwhsDWHS]))+|\g<cclass>)\])|(?<esc>\\[^cuxkg]|\\x\h\h?|\\u\h{4}|\\c.)|\\[kg](?:<\w[^>]*(?:>|\Z)|'\w[^']*(?:'|\Z))?|(?<!(?<!\\)\\[kg])[<']|\|(?!\g<rep>)|\((?:(?:\?(?:[>:=!]|(?<namedg><[_a-zA-Z][^>]*>|'[_a-zA-Z][^']*')|[xmi-]+:))?\g<main>*)\)|\(\?<[!=](?<lbpat>(?!\{(\d+)?,(\d+)?\})[^()\[\]\\*+?]|\g<esc>(?<!\\[zZ])|\g<cclass>|\((?:(?:\?:|\?\g<namedg>|\?<[!=])?\g<lbpat>*)\)|\(\?#[^)]*\))*\)|\(\?[xmi-]+\)(?!\g<rep>)|\(\?#[^)]*+\)(?!\g<rep>))+(?<rep>(?:[*+?]|\{(\d+)?,(\d+)?\})[+?]?)?)*\Z

28
क्या वे दोनों अपठनीय संस्करण नहीं हैं?
किब्बी

2
यदि आप रेगेक्स को अच्छी तरह से जानते हैं तो @Kibbee पहले वाला काफी पठनीय है।
लोजैकर

1
यह कैसे सुनिश्चित करता है कि कोई अमान्य संख्यात्मक बैकरेफेरेंस नहीं हैं?
मार्टिन एंडर

1
मुझे लगता है कि यह नहीं है। फिर, यह केवल सीमित सीमा नहीं है (ऊपर देखें)। कुछ चीजें तय की जा सकती थीं, लेकिन रेगेक्स हास्यास्पद रूप से लंबा हो जाएगा।
लोएजकेर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.