更换字符串的方式取决于是否用括号括起来

时间:2010-04-26 19:38:39

标签: php regex

我希望用大括号替换大括号之间的特定单词的所有实例,除非它是在双括号之间写入的,而它应该显示为使用单个大括号而不使用过滤器。 我尝试了一个代码但只适用于第一场比赛。其余的显示取决于第一个:

$foo = 'a {bar} b {{bar}} c {bar} d';
$baz = 'Chile';
preg_match_all( '/(\{?)\{(tin)\}(\}?)/i', $foo, $matches, PREG_SET_ORDER );
    if ( !empty($matches) ) {
        foreach ( (array) $matches as $match ) {
            if( empty($match[1]) && empty($match[3])) {
                $tull = str_replace( $match[0], $baz, $foo );
            } else {
                $tull = str_replace( $match[0], substr($match[0], 1, -1), $foo ) ;
            }
        }
    } 
    echo $tull;

编辑:用例:

如果我写:

“写{{bar}}输出模板。示例:我想转到{bar}。”

我希望:

“写{bar}输出模板。例如:我想去CHILE。”

2 个答案:

答案 0 :(得分:1)

你不能在一个正则表达式中执行此操作。首先使用

(?<!\{)\{bar\}(?!\})

只有在周围没有其他大括号时才匹配{bar}。即。

preg_replace('/(?<!\{)\{bar\}(?!\})/m', 'CHILE', 'Write {{bar}} to output the template. Example: I want to go to {bar}.');

将返回

Write {{bar}} to output the template. Example: I want to go to CHILE.

然后执行常规搜索和替换,将{{替换为{,将}}替换为}

答案 1 :(得分:1)

您可以使用两个正则表达式,一个用于查找双支撑项,另一个用于单支撑项。或者,可以使用回调来仅使用一个正则表达式来确定替换值。

单独的模式

$subject = 'Write {{bar}} to output the template. Example: I want to go to {bar}.';
$replacement = 'CHILE';
echo preg_replace(
    array('/(?<!\{)\{bar\}(?!\})/', '/\{\{bar\}\}/'),
    array($replacement, '{bar}'),
    $subject
);

带回调的单一模式

echo preg_replace_callback(
    '/(\{)?(\{bar\})(?(1)\})/',
    function ($match) use ($replacement) {
        if ($match[0][1] === '{') {
            return $match[2];
        }
        return $replacement;
    },
    $subject
);

最后,你是为一个硬编码标签(总是bar)做这个吗?还是标签部分是一些变化的替换字符串的关键?