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


Match pattern and exclude substrings with preg_match_all

我需要找到位于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的shorter,它最终直接返回字符串而不返回联接数组?我试过用一些环视表情,但找不到合适的。

$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
$r="stuffSTARTthisPADDINGisENDstuffstuffSTARTwhatPADDINGIwantPADDINGtoPADDINGfindENDstuff" ;
preg_match_all('/(?:START)(.*?)(?:END)/',str_replace('PADDING','',$r),$m);
var_dump(implode(' ',$m[1]));

可以,但我想你想要更快的。

您也可以像这样使用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