Php 正则表达式捕获第一个可选字符串之前的所有内容
我想捕获一个模式,但不包括带有preg_match的可选其他模式的第一个实例,例如:Php 正则表达式捕获第一个可选字符串之前的所有内容,php,regex,Php,Regex,我想捕获一个模式,但不包括带有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的第一个实
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'
试试这个:(.*)(:EFG |$)
这将匹配任何字符(尽可能少),直到找到EFG。您可以使用
'/(.*?)(?=EFG|$)/'
您可以在不太混乱的情况下获得结果: 只需检查要匹配的模式的更简单版本,如果不匹配,则使用原始字符串:
<?php
$match = 'Q$TQ@#%GEFGw35hqb';
if (preg_match('/^(.*)EFG/', $match, $matches)) {
$match = $matches[1];
}
echo $match;
另一种方法:
$str = 'Q$TQ@#%GEFGw35hqb';
$res = preg_split('/EFG/', $str);
print_r($res);
将preg_match()
与使用惰性匹配和前瞻性的模式一起使用,要比仅将preg_replace()
与贪婪匹配(且不使用前瞻性)一起使用以及仅用空字符串替换可选匹配采取更多步骤。如果针不存在,则字符串中没有任何更改。超级容易
代码:()
输出:
array (
0 => 'ABCD',
1 => '@Q%HG@H%hg afdgwsa g weg#D D',
2 => '@Q%HD',
3 => 'No needle in the haystack',
)
问题是它不会匹配不包含EFGRight的字符串,哦!也要匹配行尾字符。(更新的答案。)抱歉@Josh M,@Jens击败了你:P没关系,我的错是没有满足要求。注意,即使是更新的版本也不正确:它实际上在结果中包含可选字符串(而问题是“在第一个可选字符串之前捕获所有内容”)啊,非常好-我没有想到匹配EFG或结尾:)是的,我也可以用stripos
做类似的事情,但我想我应该了解一下regex-它更整洁(是的;)但是,如果性能是一个问题,您应该使用strpos
;)或者更好的是list($match)=preg_split('/EFG/',$haystack)
直接将字符串捕获到VARABLE:)使用带有文字模式的preg_
调用是不必要的开销。为什么不直接用EFG分解()
?
array (
0 => 'ABCD',
1 => '@Q%HG@H%hg afdgwsa g weg#D D',
2 => '@Q%HD',
3 => 'No needle in the haystack',
)