How to not match given prefix in RegEx without negative lookbehind?

Viewed 167

Goal

The goal is matching a string in JavaScript without certain delimiters, i.e. a string between two characters (the characters can be included in the match).
For example, this string should be fully matched: $ test string $. This can appear anywhere in a string. That would be trivial, however, we want to allow escaping the syntax, e.g. The price is 5\$ to 10\$.

Summarized:

  • Match any string that is enclosed by two $ signs.
  • Do not match it if the dollar signs are escaped using \$.

Solution using negative lookbehind

A solution that achieves this goal perfectly is: (?<!\\)\$(.*?)(?<!\\)\$.

Problem

This solution uses negative lookbehind, which is not supported on Safari. How can the same matches be achieved without using negative lookbehind (i.e. on Safari)?


A solution that partially works is (?<!\\)\$(.*?)(?<!\\)\$. However, this will also match the character in front of the $ sign if it is not a \.

2 Answers

You might rule out what you don't want by matching it, and capture what you want to keep in group 1

\\\$.*?\$|\$.*?\\\$|(\$.*?\$)

Regex demo

You may use this regex and grab your inner text using capture group #1 as you are already doing in your current regex using lookbehind:

(?:^|[^\\])\$((?:\\.|[^$])*)\$

RegEx Demo

RegEx Details:

  • (?:^|[^\\]): Match start position or a non-backslash character in a non-capturing group
  • \$: Match starting $
  • (: Start capturing group
    • (?:\\.|[^$])*: Match any escaped character or a non-$ character. Repeat this group 0 or more times
  • ): End capturing group
  • \$: Match closing $

PS: This regex will give same matches as your current regex: (?<!\\)\$(.*?)(?<!\\)\$

Related