Is there a regular expression to detect a valid regular expression?

Is it possible to detect a valid regular expression with another regular expression? If so please give example code below.


/
^                                             # start of string
(                                             # first group start
  (?:
    (?:[^?+*{}()[]|]+                      # literals and ^, $
     | .                                    # escaped characters
     | [ (?: ^?. | ^[^] | [^^] )     # character classes
          (?: [^]]+ | . )* ]
     | ( (?:?[:=!]|?<[=!]|?>)? (?1)?? )  # parenthesis, with recursive content
     | (? (?:R|[+-]?d+) )                 # recursive matching
     )
    (?: (?:[?+*]|{d+(?:,d*)?}) [?+]? )?   # quantifiers
  | |                                        # alternative
  )*                                          # repeat content
)                                             # end first group
$                                             # end of string
/

This is a recursive regex, and is not supported by many regex engines. PCRE based ones should support it.

Without whitespace and comments:

/^((?:(?:[^?+*{}()[]|]+|.|[(?:^?.|^[^]|[^^])(?:[^]]+|.)*]|((?:?[:=!]|?<[=!]|?>)?(?1)??)|(?(?:R|[+-]?d+)))(?:(?:[?+*]|{d+(?:,d*)?})[?+]?)?||)*)$/

.NET does not support recursion directly. (The (?1) and (?R) constructs.) The recursion would have to be converted to counting balanced groups:

^                                         # start of string
(?:
  (?: [^?+*{}()[]|]+                   # literals and ^, $
   | .                                  # escaped characters
   | [ (?: ^?. | ^[^] | [^^] )   # character classes
        (?: [^]]+ | . )* ]
   | ( (?:?[:=!]
         | ?<[=!]
         | ?>
         | ?<[^Wd]w*>
         | ?'[^Wd]w*'
         )?                               # opening of group
     (?<N>)                               #   increment counter
   | )                                   # closing of group
     (?<-N>)                              #   decrement counter
   )
  (?: (?:[?+*]|{d+(?:,d*)?}) [?+]? )? # quantifiers
| |                                      # alternative
)*                                        # repeat content
$                                         # end of string
(?(N)(?!))                                # fail if counter is non-zero.

Compacted:

^(?:(?:[^?+*{}()[]|]+|.|[(?:^?.|^[^]|[^^])(?:[^]]+|.)*]|((?:?[:=!]|?<[=!]|?>|?<[^Wd]w*>|?'[^Wd]w*')?(?<N>)|)(?<-N>))(?:(?:[?+*]|{d+(?:,d*)?})[?+]?)?||)*$(?(N)(?!))

Unlikely.

Evaluate it in a try..catch or whatever your language provides.


No if you are strictly speaking about regular expressions and not including some regular expression implementations that are actually context free grammars.

There is one limitation of regular expressions which makes it impossible to write a regex that matches all and only regexes. You cannot match implementations such as braces which are paired. Regexes use many such constructs, lets take [] as an example. Whenever there is an [ there must be a matching ]. Simple enough for a regex "[.*]".

What makes it impossible for regexes is that they can be nested. How can you write a regex that matches nested brackets? The answer is you can't without an infinitely long regex. You can match any number of nested parens through brute force but you can't ever match an arbitrarily long set of nested brackets.

This capability is often referred to as counting (you're counting the depth of the nesting). A regex by definition does not have the capability to count.

EDIT: Ended up writing a blog post about this: Regular Expression Limitations

链接地址: http://www.djcxy.com/p/2148.html

上一篇: 如何访问JavaScript正则表达式中的匹配组?

下一篇: 是否有正则表达式来检测有效的正则表达式?