15

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]
3

1 Answer 1

27

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.

Sign up to request clarification or add additional context in comments.

9 Comments

I don't know by looking whether this works, but I do know that it frightens me.
'/foo/i'.match(/\/(?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+\/(?:g(?:im?|m)?|i(?:gm?|m)?|m(?:gi?|i)?)?/) result is ['/foo/i']. That's not expected result.
@jules, I added parentheses in the appropriate places so that the match has the bits you expect.
"x = 2; y = x / 3; z = x/4". In this case your regex would not work
Oh, on second thoughts, if people want regex that matches with a string (or something) after it this: (?:i(?!\w*i)|g(?!\w*g)|m(?!\w*m))*(?!\w) may be more appropriate. (or ((?:([igm])(?!\w*\3))*)(?!\w))
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.