3

I am using VS Code. And I want to select all matches in italics preceding {:term}. Unfortunately VS code doesn't support lookbehind yet, so I am content with the first *.

Pattern: \*.+?(?=\*\{\:term\})

Contents:

    * *Pivot Row*{:term}
This is another term *Pivot Row*{:term}
* **List**: This is another term *Pivot Row*{:term}
*This* is *another* term repetition *Pivot Row*{:term}

Desired Selected Output:

*Pivot Row
*Pivot Row
*Pivot Row
*Pivot Row

But the following gets selected:

* *Pivot Row
*Pivot Row
* **List**: This is another term *Pivot Row
*This* is *another* term repetition *Pivot Row

Could you please suggest changes to the pattern?

Also, could you please explain why the lazy dot doesn't work?

Porcupine
  • 5,885
  • 2
  • 19
  • 28

1 Answers1

3

You may replace the lazy dot (.+?) with a greedily quantified negated character class [^*]*:

\*[^*]*(?=\*\{:term})

See the regex demo.

NOTE: Note that starting with VSCode 1.29, you need to enable search.usePCRE2 option to enable lookaheads in your regex patterns.

NOTE2: You can use infinite-width lookahead and lookbehind without any constraint beginning with Visual Studio Code v.1.31.0 release, and you do not need to set any PCRE2 option now.

Note that . matches any char but a line break char, hence, it can match a * char, too. Since the regex engine searches for matches from left to right, and starts matching beginning with the leftmost occurrence, the first * char on the lines got matched with the first \* pattern and .+? matched as few chars as necessary to complete a valid match, "gobbling up" all * symbols on its way to *{:term}.

Details

  • \* - a * char
  • [^*]* - 0+ chars other than *, as many as possible
  • (?=\*\{:term}) - a positive lookahead that requires *{:term} substring to appear immediately to the right of the current location.

Note that } and : are not special and do not have to be escaped.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563