I want to capture a pattern upto but not including the first instance of an optional other pattern with preg_match, eg:
ABCDEFGwTW$%
Another way to do it:
$str = 'Q$TQ@#%GEFGw35hqb';
$res = preg_split('/EFG/', $str);
print_r($res);
You can have the result with a lot less confusion:
Just check a simpler version of the pattern to match, and if not, use the original string:
<?php
$match = 'Q$TQ@#%GEFGw35hqb';
if (preg_match('/^(.*)EFG/', $match, $matches)) {
$match = $matches[1];
}
echo $match;
Try this: (.*?)(?:EFG|$)
This will match any character (as few as possible) until it finds EFG.
You can use
'/(.*?)(?=EFG|$)/'
Using preg_match()
with a pattern that uses lazy matching and a lookahead is going to take more steps than just using preg_replace()
with greedy matching (and no lookarounds) and simply replacing the optional match with an empty string. If the needle doesn't exist, then nothing is changed in the string. Super easy.
Code: (Demo)
$strings = [
'ABCDEFGwTW$%',
'@Q%HG@H%hg afdgwsa g weg#D DEFG',
'@Q%HDEFG@H%hg afdgwsa g weg#D DEFG',
'No needle in the haystack',
];
var_export(preg_replace('/EFG.*/', '', $strings));
Output:
array (
0 => 'ABCD',
1 => '@Q%HG@H%hg afdgwsa g weg#D D',
2 => '@Q%HD',
3 => 'No needle in the haystack',
)