Skip to content
Advertisement

regex riddle. want results: ‘onetwothree’, ‘onetwo’, ‘twothree’ but NOT ‘two’. Positive lookahead maybe?. For currency extraction

confused with some basic regex logic. Using simple example:

(one)(two)(three)

I want regex to catch:

onetwothree
onetwo
   twothree

but NOT

   two

and catching in groups (one)(two)(three).

I know I can use positive lookahead on ‘two’ so that it is only preceded by ‘one’:

(one)?((?<=one)two)(three)? 

but then I cannot get the ‘twothree’ result

The real world need is for currency:

group one:   [$¥£€₹]
group two:   ((?:d{1,10}[,. ])*d{1,10})
group three: ( ?(?:[$¥£€₹]|AUD|USD|GBP|EURO?S?b))

so I want to get these results:

$20,000 AUD
$20,000
 20,000 AUD

but NOT

 20,000

help appreciated!

PS need matches in groups (one)(two)(three) or (one)(two) or (two)(three).

Advertisement

Answer

Here’s a pure regex response:

(ONE)?TWO(?(1)(THREE)?|THREE)

Using conditionals, you can check to see if the first group matched, and if it did, then you can make the last group mandatory.

(ONE)?TWO(?(1)(THREE)?|THREE)
^     ^  ^^^^^   ^       ^
1     2    3     4       5

1: Try to match ONE. If you can't find it, no big deal.
2: You absolutely must have TWO.
3: If the first group DID match (ONE), then...
4: ... Use the first result
5: Otherwise use the second result

With this, we just make the first result be optional, so if we match ONE, then THREE is optional. If we miss ONE, then THREE is mandatory.

ONE
TWO
THREE
ONETWO       // Matches! (e.g: $20,000)
ONETHREE
TWOTHREE     // Matches! (e.g: 20,000 AUD)
ONETWOTHREE  // Matches! (e.g: $20,000 AUD)

Try it online!

Read more about conditional regex patterns in PHP here.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement