Convert JS regex to not use lookbehind

Viewed 70

Early in the development of a web project I work on I created this regex /(?<!\\)\w?\$.+?(?<!\\)\$/ which aims to match $ any text here$ as long as the first and last $ are not preceded by \.

A few examples are shown here https://regex101.com/r/Y1Uml9/1/

The regex works perfectly until I realised that iOS Safari and Chrome do not support lookbehinds. I tried to modify the regex myself but my basic regex skills were not able to produce a working one.

Any suggestions how to convert the regex so it works on iOS?

1 Answers

You can use

/((?:^|[^\\])(?:\\\\)*)\$([^\\$]*(?:\\[\w\W][^\\$]*)*)\$/g

See the regex demo.

Basically, capture the part before the "actual" match, capture the part of the match you need to keep when replacing.

Details:

  • ((?:^|[^\\])(?:\\\\)*) - Group 1: start of string or any char other than \ and then zero or more repetitions of double backslash
  • \$ - a $ char
  • ([^\\$]*(?:\\[\w\W][^\\$]*)*) - Group 2:
    • [^\\$]* - zero or more chars other than \ and $
  • (?:\\[\w\W][^\\$]*)* - zero or more repetitions of
    • \\[\w\W] - a \ followed with any char
    • [^\\$]* - zero or more chars other than \ and $
  • \$ - a $ char

See a JavaScript demo:

const regex = /((?:^|[^\\])(?:\\\\)*)\$([^\\$]*(?:\\[\w\W][^\\$]*)*)\$/g;
const str = String.raw`$ some test here$
$ some text here with inner \$ $
\$ this should not be matched\$`;
console.log( str.replace(regex, '$1<<START>>$2<<END>>') );

Related