如何在第一个特定字符处停止替换

时间:2013-06-08 17:33:31

标签: php preg-replace design-patterns

我想隐藏特定标签,直到某些内容中的结束标签,但我无法使其正常工作 这就是我所拥有的:

$fnc_patterns   =   "/\[display=[^!]+\]?.*\[\/display=[^!]+\]/";
$str           =    preg_replace($fnc_patterns, '', $str);

$str = "Dummy text text dummy [display=hide]hide this[/display=hide] but it also [display=no_hide]hides this[/display=no_hide] and not [display=hide]this[/display=hide] :(!";
//Outputs: Dummy text text dummy :(!

但它应输出Dummy text text dummy but it also hides this :(! 我在此函数之前替换[display=no_hide]并关闭tage。问题是,它只是替换[display=XXX][/display=XXX]之间的所有内容,但它应该在第一次结束标记遇到时停止。我怎么能这样做?

(请注意,XXX可以是所有内容,而不仅仅是hideno_hide

提前致谢!

3 个答案:

答案 0 :(得分:1)

你应该试试这个。它会从display:someworddisplay=someword搜索到下一个匹配的结尾标记。我使用“不情愿匹配”运算符*?来确保它不会从第一个打开的标记转到最后一个关闭标记。

$fnc_patterns   =   "/(\[display[=:]([^\]]+)\].*?\[\/display[=:]\2\])/"

答案 1 :(得分:0)

扩展greedybuddha的答案,如果你还想隐藏[display=no_hide]hides this[/display=no_hide],请使用:

(\[display[=:][no_]*hide\].*?\[\/display[=:][no_]*hide\])

示例:http://www.debuggex.com/embed/KRhwg3S-_8jnwQfG

答案 2 :(得分:0)

如果您想轻松选择要隐藏的标签,可以使用 DEFINE 语法。此模式可以处理嵌套标记。

$str = <<<LOD
Shw1 [display=marmot]Hid1[/display=marmot]Shw2
[display=nutria]Hid2[display=badger]Hid3[/display=badger]Hid4[/display=nutria]
[display=marmot]Hid5[display=marmot]Hid6[/display=marmot]Hid7[/display=marmot]
Shw3 [display=weasel]Shw4[/display=weasel]
LOD;

$pattern = <<<'LOD'
~
    # definitions
    (?(DEFINE)(?<terms>(?>nutria|marmot|badger)))

    # pattern
    \[display([=:]\g<terms>)]
        (?>[^][]++|(?R)?)+
    \[/display\2]
~x
LOD;

echo preg_replace ($pattern, '', $str);

请注意,如果没有 DEFINE 语法,您可以这样做:

$hidden_tags = array('nutria', 'marmot', 'badger');
$terms = implode('|', $hidden_tags);
$pattern = '~\[display([=:](?>'.$terms.')](?>[^][]++|(?R)?)+\[/display\1]~';