正则表达式验证正则表达式[关闭]


17

构建一个将接受正则表达式字符串作为输入的正则表达式,并检查其是否有效。基本上,您的正则表达式应该能够验证自己。(任何无效的正则表达式都不应进行验证,因此您不能使用.*。;))

您的风味必须得到众所周知的实现(Perl,sed,grep,gawk等)的完全支持,并且必须完全支持那些实现所支持的功能。[不用担心律师说话;我只是想消除所有可能导致智能***的漏洞。]


我会对此进行,但是我担心它会给那些知道和使用非功能丰富的风味的人带来优势。还是我的担心没有根据?


8
不可能,任意的嵌套括号使正则表达式成为上下文无关的语法,(用波兰记号替换它也需要堆栈)
棘手怪胎

@ratchet Augh,您可能是对的。
Mateen Ulhaq

1
存在一些常规语言的扩展名,这些扩展名可能允许匹配方括号,但我不知道该怎么做
棘手怪胎

8
Perl正则表达式一定有可能。
彼得·泰勒

1
用现代语言实现的@BrianVandenberg正则表达式几乎都是非常规的……添加反向引用后,您就可以匹配非常规语言。而且,Perl / PCRE和.NET都足够强大,可以匹配正确的嵌套。
Martin Ender 2014年

Answers:


22

红宝石

我试图尽可能地匹配Ruby的regex风格的实际语法,但是有一些怪癖:它接受了一些实际上是无效的lookbehind(例如(?<=(?<!))),并且可以识别空字符范围(例如)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
他们都不都是不可读的版本吗?
Kibbee

2
@Kibbee如果您对正则表达式非常了解,则第一个可读性很强。
Lowjacker 2011年

1
如何确保没有无效的数字反向引用?
Martin Ender 2014年

1
我想不是。再说一次,它不是唯一的限制(见上文)。有些事情可以解决,但是正则表达式会变得很长。
Lowjacker 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.