我想捕获一个模式,但不包括preg_match的可选其他模式的第一个实例,例如:
ABCDEFGwTW$% | capture ABCD
@Q%HG@H%hg afdgwsa g weg#D DEFG | capture @Q%HG@H%hg afdgwsa g weg#D D
@Q%HDEFG@H%hg afdgwsa g weg#D DEFG | capture @Q%HD
因此,在上述情况下,捕获字符串EFG
的第一个实例之前的任何内容。另外,如果EFG
字符串不存在,那么我想捕获整个字符串。
我原以为以下方法可行,但没有这样的运气:
$pattern = '/(.*)(?:EFG)?/';
preg_match($pattern, 'Q$TQ@#%GEFGw35hqb', $matches);
print_r($matches);
//should give: 'Q$TQ@#%G'
答案 0 :(得分:18)
您可以使用
'/(.*?)(?=EFG|$)/'
答案 1 :(得分:2)
试试这个:(.*?)(?:EFG|$)
这将匹配任何字符(尽可能少),直到找到EFG。
答案 2 :(得分:1)
另一种方法:
$str = 'Q$TQ@#%GEFGw35hqb';
$res = preg_split('/EFG/', $str);
print_r($res);
答案 3 :(得分:0)
你可以减少混乱的结果:
只需检查一个更简单的模式版本即可,如果没有,请使用原始字符串:
<?php
$match = 'Q$TQ@#%GEFGw35hqb';
if (preg_match('/^(.*)EFG/', $match, $matches)) {
$match = $matches[1];
}
echo $match;
答案 4 :(得分:0)
将preg_match()
与使用懒惰匹配和先行模式的模式结合使用,比仅将preg_replace()
与贪婪匹配(且没有环顾四周)并将简单的可选匹配替换为空匹配要采取更多的步骤串。如果针不存在,则字符串中的任何内容都不会更改。超级容易。
代码:(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));
输出:
array (
0 => 'ABCD',
1 => '@Q%HG@H%hg afdgwsa g weg#D D',
2 => '@Q%HD',
3 => 'No needle in the haystack',
)