Honestly, I would just discard any lookaheads/lookbehinds and just define all cases separately and then combine them. It is more rebust, easier to reason with and understand and more effective.
So do
(^(groupone)(grouptwo)$)|(^(groupone)(grouptwo)(groupthree)$)|(^(grouptwo)(groupthree)$)
For example:
$groupone = '[$¥£€₹]';
$grouptwo = '(?:\d{1,10}[,. ])*\d{1,10}';
$groupthree = ' ?([$¥£€₹]|AUD|USD|GBP|EURO)';
$caseone = "^($groupone)($grouptwo)$";
$casetwo = "^($groupone)($grouptwo)($groupthree)$";
$casethree = "^($grouptwo)($groupthree)$";
$allcases = "/($caseone)|($casetwo)|($casethree)/";
preg_match($allcases, '20,000 AUD', $matches);
print_r($matches); // matches, preg_match returns 1
preg_match($allcases, '$20,000', $matches);
print_r($matches); // matches, preg_match returns 1
preg_match($allcases, '$20,000 AUD', $matches);
print_r($matches); // matches, preg_match returns 1
preg_match($allcases, '20,000', $matches);
print_r($matches); // empty, preg_match returns 0
To make results look nicer (skip empty results, duplicates, extra whitespaces etc) I'd additionally use a cleanup function:
<?php
$groupone = '[$¥£€₹]';
$grouptwo = '(?:\d{1,10}[,. ])*\d{1,10}';
$groupthree = ' ?([$¥£€₹]|AUD|USD|GBP|EURO)';
$caseone = "^($groupone)($grouptwo)$";
$casetwo = "^($grouptwo)($groupthree)$";
$casethree = "^($groupone)($grouptwo)($groupthree)$";
$allcases = "/($caseone)|($casetwo)|($casethree)/";
function cleanup($arr) {
# trim trailing, ending whitespace
$newarr = array_map('trim', $arr);
# remove empty values
$newarr = array_filter($newarr, function($value) { return $value !== ''; });
# remove duplicates
$newarr = array_unique($newarr);
# we're only interested about the values
return array_values($newarr);
}
preg_match($allcases, '20,000 AUD', $matches);
print_r(cleanup($matches));
preg_match($allcases, '$20,000', $matches);
print_r(cleanup($matches));
preg_match($allcases, '$20,000 AUD', $matches);
print_r(cleanup($matches));
preg_match($allcases, '20,000', $matches);
print_r(cleanup($matches));
Which would get you results like
Array
(
[0] => 20,000 AUD
[1] => 20,000
[2] => AUD
)
Array
(
[0] => $20,000
[1] => $
[2] => 20,000
)
Array
(
[0] => $20,000 AUD
[1] => $
[2] => 20,000
[3] => AUD
)
Array
(
)
Edit: if you want the groups to be the same, you can use named groups like
$groupone = '(?<currencyprefix>[$¥£€₹])';
$grouptwo = '((?:\d{1,10}[,. ])*\d{1,10})';
$groupthree = ' ?(?<currencypostfix>([$¥£€₹]|AUD|USD|GBP|EURO))';
$caseone = "^$groupone$grouptwo$";
$casetwo = "^$grouptwo$groupthree$";
$casethree = "^$groupone$grouptwo$groupthree$";
$allcases = "/(?J)($caseone)|($casetwo)|($casethree)/";
function cleanup($arr) {
$currencyprefix = isset($arr['currencyprefix']) ? $arr['currencyprefix'] : null;
$currencypostfix = isset($arr['currencypostfix']) ? $arr['currencypostfix'] :null;
return array($currencyprefix, $currencypostfix);
}
if (preg_match($allcases, '20,000 AUD', $matches))
print_r(cleanup($matches));
if (preg_match($allcases, '$20,000', $matches))
print_r(cleanup($matches));
if (preg_match($allcases, '$20,000 AUD', $matches))
print_r(cleanup($matches));
if (preg_match($allcases, '20,000', $matches))
print_r(cleanup($matches));
Which would get you
Array
(
[0] =>
[1] => AUD
)
Array
(
[0] => $
[1] =>
)
Array
(
[0] => $
[1] => AUD
)
Or, use named keys in end results too:
$groupone = '(?<currencyprefix>[$¥£€₹])';
$grouptwo = '((?:\d{1,10}[,. ])*\d{1,10})';
$groupthree = ' ?(?<currencypostfix>([$¥£€₹]|AUD|USD|GBP|EURO))';
$caseone = "^$groupone$grouptwo$";
$casetwo = "^$grouptwo$groupthree$";
$casethree = "^$groupone$grouptwo$groupthree$";
$allcases = "/(?J)($caseone)|($casetwo)|($casethree)/";
function cleanup($arr) {
$newarr = array_filter($arr, function($var){ return !empty($var); });
return array_filter($newarr, "is_string", ARRAY_FILTER_USE_KEY);
}
if (preg_match($allcases, '20,000 AUD', $matches))
print_r(cleanup($matches));
if (preg_match($allcases, '$20,000', $matches))
print_r(cleanup($matches));
if (preg_match($allcases, '$20,000 AUD', $matches))
print_r(cleanup($matches));
if (preg_match($allcases, '20,000', $matches))
print_r(cleanup($matches));
With results:
Array
(
[currencypostfix] => AUD
)
Array
(
[currencyprefix] => $
)
Array
(
[currencyprefix] => $
[currencypostfix] => AUD
)