Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript regex to match a regex

I'm working on a special regex to match a javascript regex.

For now I have this regex working:

/\/(.*)?\/([i|g|m]+)?/

For example:

'/^foo/'.match(/\/(.*)?\/([i|g|m]+)?/) => ["/^foo/", "^foo", undefined]
'/^foo/i'.match(/\/(.*)?\/([i|g|m]+)?/) => ["/^foo/i", "^foo", "i"]

Now I need to get this regex working with:

'^foo'.match(/\/(.*)?\/([i|g|m]+)?/) => ["^foo", "^foo", undefined]

Unfortunately my previous regex doesn't work for that one.

Can someone help me to find a regex matching this example (and others too):

'^foo'.match([a regex]) => ["^foo", "^foo", undefined]
like image 210
julesbou Avatar asked Jul 24 '13 19:07

julesbou


People also ask

How do I match a regex pattern?

To match a character having special meaning in regex, you need to use a escape sequence prefix with a backslash ( \ ). E.g., \. matches "." ; regex \+ matches "+" ; and regex \( matches "(" . You also need to use regex \\ to match "\" (back-slash).

How do you match a pattern in JavaScript?

The match module returns a function that takes two parameters: an array of patterns and closures, and a value to match against. The array of patterns and closures is itself an array containing the pattern to match on and a closure to execute once the pattern is matched. If no match is made the module returns undefined.

How do you check if a string matches a regex in JS?

If you need to know if a string matches a regular expression RegExp , use RegExp.prototype.test() . If you only want the first match found, you might want to use RegExp.prototype.exec() instead.

What does (? I do in regex?

All modes after the minus sign will be turned off. E.g. (? i-sm) turns on case insensitivity, and turns off both single-line mode and multi-line mode. Not all regex flavors support this.


1 Answers

A regular expression to match a regular expression is

/\/((?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+)\/((?:g(?:im?|mi?)?|i(?:gm?|mg?)?|m(?:gi?|ig?)?)?)/

To break it down,

  1. \/ matches a literal /
  2. (?![*+?]) is necessary because /* starts a comment, not a regular expression.
  3. [^\r\n\[/\\] matches any non-escape sequence character and non-start of character group
  4. \[...\] matches a character group which can contain an un-escaped /.
  5. \\. matches a prefix of an escape sequence
  6. + is necessary because // is a line comment, not a regular expression.
  7. (?:g...)? matches any combination of non-repeating regular expression flags. So ugly.

This doesn't attempt to pair parentheses, or check that repetition modifiers are not applied to themselves, but filters out most of the other ways that regular expressions fail to syntax check.

If you need one that matches just the body, just strip off everything else:

/(?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+/

or alternatively, add "/" at the beginning and end of your input.

like image 165
Mike Samuel Avatar answered Oct 11 '22 00:10

Mike Samuel