正在忽略可选的正则表达式匹配

时间:2013-05-19 21:52:57

标签: php regex preg-replace

我在PHP中有一些正则表达式没有做我想要的。

我想要的是什么:

[segment type="segment_name"]more text here[/segment]

更改为:

[segmentclass='segment_name segment']more text here[/segment]

[segment]more text here[/segment]

更改为:

[segmentclass=' segment']more text here[/segment]

这就是我所拥有的:

$pattern = '/(\[segment.*?)(type=\"(.+?)\")?(.*?\[\/segment\])/is';
$replacement = '$1class=\'$3 segment\'$4';
$content = preg_replace($pattern, $replacement, $content);

有没有人有任何想法?的? after(type = \“(。+?)\”)是使该块可选。似乎替换只是跳过它,因为它是可选的。我觉得我的某个地方有贪婪的问题,但是我无法解决它。

如果您对我能做到的另一种方式有任何想法,请回复。

1 个答案:

答案 0 :(得分:1)

第一个细分受众群没有结束括号]。因为它找不到该结束块的匹配项,.*?会匹配[/segment]以外的所有内容,忽略您放在那里的可选组。

如果可以的话,你应该避免使用任何形式的.*,这是一个经典的情况,否定的角色类会是适当的。 [^\]]*是更好的选择。

这个字符类在这里是一个更好的选择的原因是它会使正则表达式失败,而不是给你一个误报。

您在问题中列出的输入以及segment的特定匹配让我相信您的正则表达式过于复杂,并且替换非常混乱。此更新的正则表达式也不需要DOTALL标志。

$pattern = '/\[segment(?: type="([^"]+)")?\]/i';
$replacement = '[segmentclass=\'$1 segment\']';