Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex - Invalid target for quantifier which converting C# Regex to JavaScript Regex

I am trying to convert C# email regular expression, which I have taken from MSDN sample

@"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@)) (?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$"

which is like this:

^(?(")(".+?"@)|(([0-9a-zA-Z]((\.(?!\.))|[^!#\$%&\s'\*/=\?\^`\{\}\|~])*)(?<=[-+0-9a-zA-Z_])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]*\.)+[a-zA-Z]{2,6}))$

but I am getting error for:

? : Invalid target for qualifier.

?<= : Lookbehind is not supported in JavaScript

I have need help in converting above Regex

like image 710
Ramesh Chandra Avatar asked Oct 31 '22 13:10

Ramesh Chandra


1 Answers

In .NET, this regex must have been used with IgnorePatternWhitespace and IgnoreCase flags since there is a space that prevents matching. Here is a demo.

The problems you encounter when porting the regex to JS are caused by the fact that JS regex does not support lookbehinds and conditionals.

There is a conditional workaround for JS: .NET (?(")"[^"]*"|\w+) can be translated as (?:(?=")"[^"]*"|(?!")\w+).

The lookbehinds are difficult to convert, but here, the first lookbehind does not seem appropriate. You are looking to find the closest set of unescaped double quotes. You can do it with "[^"\\]*(?:\\.[^"\\]*)*".

The second lookbehind is just checking if @ is preceded by a letter or digit character. The easiest way to handle this is to add [a-z0-9] character class to the left of the @ symbol and apply a ? quantifier to the first group of this alternative, making a digit or a letter appear before @ and the 1-character user part would still get matched.

So, you can use

/^(?:(?=")("[^"\\]*(?:\\.[^"\\]*)*"@)|(?!")(([0-9a-z]((\.(?!\.))|[-!#$%&'*+\/=?^`{}|~\w])*)?[a-z0-9]@))(?:(?=\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(?!\[)(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][-a-z0-9]{0,22}[a-z0-9]))$/i

See demo (note I also removed some unnecessary escape symbols).

like image 181
Wiktor Stribiżew Avatar answered Nov 08 '22 03:11

Wiktor Stribiżew