正则表达式在第一个可选字符串之前捕获所有内容

时间:2011-05-12 14:13:49

标签: 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的第一个实例之前的任何内容。另外,如果EFG字符串不存在,那么我想捕获整个字符串。

我原以为以下方法可行,但没有这样的运气:

$pattern = '/(.*)(?:EFG)?/';
preg_match($pattern, 'Q$TQ@#%GEFGw35hqb', $matches);
print_r($matches);
//should give: 'Q$TQ@#%G'

5 个答案:

答案 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',
)