Anatomy of your pattern
(?=.*(USD))(?(1)\d+|[a-zA-Z])
| | | | | |_______
| | | | | Else match a single char a-zA-Z
| | | | |
| | | | |__
| | | | If group 1 exists, match 1+ digits
| | | |
| | | |__
| | | Test for group 1
| | |_________________
| | If Clause
| |___
| Capture group 1
|__________
Positive lookahead
About the pattern you tried
The positive lookahead is not anchored and will be tried on each position. It will continue the match if it returns true, else the match stops and the engine will move to the next position.
Why does the pattern not match?
On the first position the lookahead is true as it can find USD on the right.
It tries to match 1+ digits, but the first char is U which it can not match.
USD 100
⎸
First position
From the second position till the end, the lookahead is false because it can not find USD on the right.
USD 100
⎸
Second position
Eventually, the if clause is only tried once, where it could not match 1+ digits. The else clause is never tried and overall there is no match.
For the YEN 300 part, the if clause is never tried as the lookahead will never find USD at the right and overall there is no match.
Interesting resources about conditionals can be for example found at rexegg.com and regular-expressions.info
If you want the separate matches, you might use:
\bUSD \K\d+|[A-Z](?=[A-Z]* \d+\b)
Explanation
\bUSD Match USD and a space
\K\d+ Forget what is matched using \K and match 1+ digits
| Or
[A-Z] Match a char A-Z
(?=[A-Z]* \d+\b) Assert what is on the right is optional chars A-Z and 1+ digits
regex demo
Or using capturing groups:
\bUSD \K(\d+)|([A-Z])(?=[A-Z]* \d+\b)
Regex demo
\b(?:USD (\d+)|(?!USD\b)(\w+) \d+)\bgets close, except that it captures the entire non USD currency symbol, rather than capturing each letter in a separate capture group. To capture each letter, you might need some tricks in Ruby.YENwould also do the trick just fine. It doesn't have to be each and every letter in an array. I'm wondering though; Why doesn't the look ahead work?(?:(USD) )?(?(1)(\d+)|([a-zA-Z]))rubular.com/r/quQSSLzsj0Om1q Then check for group 2 or group 3USDwill match because the positive lookahead requires it.