使用 preg_match_all 匹配模式并排除子字符串

4

我需要找到所有出现在 START 和 END 之间的字符串,但需要排除匹配字符串中的 PADDING 子字符串。我找到的最佳方法是

$r="stuffSTARTthisPADDINGisENDstuffstuffSTARTwhatPADDINGIwantPADDINGtoPADDINGfindENDstuff" ;
preg_match_all('/START(.*?)END/',str_replace('PADDING','',$r),$m);
print(join($m[1]));
> thisiswhatIwanttofind

我希望使用最小的代码量来实现这个功能:有没有一种更短的方法只用 preg_match_all 而不使用 str_replace,并且直接返回字符串而不是数组?我已经尝试了一些回溯表达式,但是找不到合适的方法。


“PADDING”是将出现在“START”和“END”之间的字面文本吗?否则,“PADDING”会是什么样的字符? - Kenneth K.
PADDING是一个固定的ASCII字符串。 - Emilio
3个回答

1
$r="stuffSTARTthisPADDINGisENDstuffstuffSTARTwhatPADDINGIwantPADDINGtoPADDINGfindENDstuff";
echo preg_replace('/(END.*?START|PADDING|^[^S]*START|END.*$)/', '', $r);

这应该使用单个正则表达式模式返回 thisiswhatIwanttofind

解释:

END.*?START  # Replace occurrences of END to START
PADDING      # Replace PADDING
^[^S]*START  # Replace any character until the first START (inclusive)
END.*$       # Replace the last END and until end of the string

0
$r="stuffSTARTthisPADDINGisENDstuffstuffSTARTwhatPADDINGIwantPADDINGtoPADDINGfindENDstuff" ;
preg_match_all('/(?:START)(.*?)(?:END)/',str_replace('PADDING','',$r),$m);
var_dump(implode(' ',$m[1]));

可以运行,但我猜你想要更快的东西。


0

你也可以像这样使用 preg_replace_callback:

$str = preg_replace_callback('#.*?START(.*?)END((?!.*?START.*?END).*$)?#', 
           function ($m) {
               print_r($m);
               return str_replace('PADDING', '', $m[1]);
           }, $r);

echo $str . "\n"; // prints thisiswhatIwanttofind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接