1

My title probably doesn't explain exactly what I mean. Take the following string:

POWERSTART9^{{2|3}}POWERENDx{{3^EXSTARTxEXEND}}=POWERSTART27^{{1|4}}POWEREND

What I want to do here is isolate the parts that are like this:

{{2|3}} or {{1|4}}

The following expression works to an extent, it selects the first one {{2|3}} with no issue:

\{\{(.*?)\|(.*?)\}\}

The problem is, it's not just selecting the first if {{2|3}} and the second of {{1|4}} because after the first one we have {{3^EXSTARTxEXEND}} so it's taking the starting point from {{3 and going right until the end of the second part I want |4}}

Here it is highlighted on RegExr:

enter image description here

I've never been great with regex and can't work out how to stop it doing that. Any ideas? I basically want it to only match the exact pattern and not something that contains it.

Glen Elkins
  • 867
  • 9
  • 30

2 Answers2

1

You may use

\{\{((?:(?!{{).)*?)\|(.*?)}}

See the regex demo.

If there can be no { and } inside the {{...}} substrings, you may use a simpler \{\{([^{}|]*)\|([^{}]*)}} expression (see demo).

Details

  • \{\{ - a {{ substring
  • ((?:(?!{{).)*?) - Capturing group 1: any char (.), as few as possible (*?), that does not start a {{ char sequence (tempered greedy token)
    • [^{}|]* - any 0 or more chars other than {, } and |
  • \| - a | char
  • (.*?) - Capturing group 2: any 0 or more chars, as few as possible
    • [^{}]* - any 0 or more chars other than { and }
  • }} - a }} substring.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Will this work for say 10 of them in the string or only 2? – Glen Elkins Mar 10 '19 at 20:35
  • Wow great. I need to read your comment a bit more and check against regex docs because I'm not fully following it, although it does work, thanks :) – Glen Elkins Mar 10 '19 at 20:37
  • @GlenElkins If you only have digits there, inside expected matches, you may even use `\{\{(\d+)\|(\d+)}}`, see https://regex101.com/r/xHDZ7G/4. It all depends on the actual requirements, the first regex is the most generic one. – Wiktor Stribiżew Mar 10 '19 at 20:59
  • 1
    The generic one is what I need thanks for your help, I will familiarise myself with he regex parts I don't know . – Glen Elkins Mar 10 '19 at 21:04
0

Try this \{\{([^\^|]*)\|([^\^|]*)\}\}

https://regex101.com/r/bLF8Oq/1