Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

regex

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

like image 659
psytek Avatar asked Oct 05 '08 17:10

psytek


People also ask

How do I check if a regular expression is valid?

new String(). matches(regEx) can be directly be used with try-catch to identify if regEx is valid. While this does accomplish the end result, Pattern. compile(regEx) is simpler (and is exactly what will end up happening anyway) and doesn't have any additional complexity.

How do I identify a regular expression?

You can check if "".search(str) throws an error to see if the str can be compiled to a valid regex though. 'cat' and 'dog' are also valid regex. They match those exact sequence of letters. Therefor, all common words are valid regex.

How do you check if the input string is a valid regular expression?

compile() function to check if our regular expression is valid or not. Then we call input() function which basically prompts user for input string. Then we use re. fullmatch() function to test if user input is a valid alphanumeric string by checking it against our regex.


1 Answers

/ ^                                             # 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         (?: [^\]\\]+ | \\. )* \]    | \( (?:\?[:=!]          | \?<[=!]          | \?>          | \?<[^\W\d]\w*>          | \?'[^\W\d]\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:

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

From the comments:

Will this validate substitutions and translations?

It will validate just the regex part of substitutions and translations. s/<this part>/.../

It is not theoretically possible to match all valid regex grammars with a regex.

It is possible if the regex engine supports recursion, such as PCRE, but that can't really be called regular expressions any more.

Indeed, a "recursive regular expression" is not a regular expression. But this an often-accepted extension to regex engines... Ironically, this extended regex doesn't match extended regexes.

"In theory, theory and practice are the same. In practice, they're not." Almost everyone who knows regular expressions knows that regular expressions does not support recursion. But PCRE and most other implementations support much more than basic regular expressions.

using this with shell script in the grep command , it shows me some error.. grep: Invalid content of {} . I am making a script that could grep a code base to find all the files that contain regular expressions

This pattern exploits an extension called recursive regular expressions. This is not supported by the POSIX flavor of regex. You could try with the -P switch, to enable the PCRE regex flavor.

Regex itself "is not a regular language and hence cannot be parsed by regular expression..."

This is true for classical regular expressions. Some modern implementations allow recursion, which makes it into a Context Free language, although it is somewhat verbose for this task.

I see where you're matching []()/\. and other special regex characters. Where are you allowing non-special characters? It seems like this will match ^(?:[\.]+)$, but not ^abcdefg$. That's a valid regex.

[^?+*{}()[\]\\|] will match any single character, not part of any of the other constructs. This includes both literal (a - z), and certain special characters (^, $, .).

like image 180
Markus Jarderot Avatar answered Sep 18 '22 15:09

Markus Jarderot