我需要多次捕获某个模式,同时还要记住之前,之后和之间的内容。例如:
一些文字“被捕获”更多的文字“被捕获”了一些 文本
唯一可以预测的是分隔要捕获的文本的标记。捕获的文本本身每次都不同。最后,我需要在捕获的部分周围放置CSS跨度,如此
some text <span class="a">"to be captured"</span> some more text <span
class="a">"to be captured"</span> some more text
我试过
if (preg_match("/(.*?)(\".*?\")(.*)/", $line, $m)
$res .= $m[1] . '<span class="a">' . $m[2] . '</span>' . $m[3];
它适用于只有一次捕获的线。使用preg_match_all并不能解决这个问题,可能我还需要更改正则表达式本身,但我不知道如何。
答案 0 :(得分:3)
您尝试过preg_replace吗?
$line = preg_replace("/(\".*?\")/",
'<span class="a">$1</span>',
$line
);
ps:我还不确定OP的问题是什么,没有例子。如果你有一组分隔符,那么regexp可能是
$str = 'some text "to be captured" some more text #to be *captured#
some more text* but I would capture that*';
echo preg_replace('/(("|#|\*).*?\\2)/s',
'<span class="a">$1</span>',
$str);
答案 1 :(得分:1)
我不了解PHP,但仅查看正则表达式,您需要搜索此内容:([^"]*)(".*?")
并替换为此$1<span class="a">$2</span>
some text "to be captured" some more text "to be captured" some more text
some text "to be captured" some more text "to be captured"
会给出这个:
some text <span class="a">"to be captured"</span> some more text <span class="a">"to be captured"</span> some more text
some text <span class="a">"to be captured"</span> some more text <span class="a">"to be captured"</span>
:: EDIT :: 这个PHP代码似乎正在运行:
$line = 'some text "to be captured" some more text "to be captured" some more text';
$line2 = preg_replace('/([^"]*)(".*?")/', htmlspecialchars('$1<span class="a">$2</span>'),$line);
echo $line2;
答案 2 :(得分:1)
您的代码无效的主要原因是第三组(.*)
吞噬了第一个引用部分之后的所有内容,包括所有剩余的引号。如果.
匹配换行符,它会占用文档其余部分的所有引号,而不仅仅是行的其余部分。
@ Cheery的解决方案通过使第三组非贪婪来解决这个问题:(.*?)
。这将有效,但只是因为第三组从未捕获任何东西。它不是消耗它所能做的一切,而是从没有消耗任何东西开始。这是可以接受的,并且在正则表达式之后没有任何东西可以强迫它消耗更多,所以它就会停在那里。
解决此问题的正确方法是仅匹配 要突出显示的部分。使用捕获组将其放回到其周围的标签中,并将剩余的文本单独留下:
$line = preg_replace('/("[^"]*")/', '<span class="a">$1</span>', $line);
事实上,您甚至不需要使用捕获组。由于匹配现在仅包含引用的部分,因此您可以使用$0
重新插入它:
$line = preg_replace('/"[^"]*"/', '<span class="a">$0</span>', $line);
编辑: @Cheery编辑了他的答案,我的评论不再适用。我认为这个答案仍然会增加一些价值,所以我会继续把它留下来。
答案 3 :(得分:0)
如果您基本上想要捕获所有内容,但将特定部分分开,那么您可以使用preg_split
:
$matchs_and_in_between = preg_split('/"(.*?)"/', $src,
PREG_SPLIT_DELIM_CAPTURE);
诀窍是旗帜。而且你必须遍历结果数组。每个第二个条目都是您使用正则表达式指定的条目。其余的是中间部分。