简体   繁体   English

根据是否用大括号括起来,以不同的方式替换字符串

[英]Replace strings differently depending if is enclosed in braces or not

I want to replace all instances of an specific words between braces with something else, unless it is written between double braces, while it should show as is it was written with single braces without the filter. 我想用其他东西替换括号内特定单词的所有实例,除非它写在双括号之间,而它应该显示为用单括号写而没有过滤器。 I have tried a code but only works for the first match. 我尝试了一个代码,但仅适用于第一场比赛。 The rest are shown depending of the first one: 其余的显示取决于第一个:

$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;

EDIT: use case: 编辑:用例:

If I write: 如果我写:

"Write {{bar}} to output the template. Example: I want to go to {bar}." “写{{bar}}以输出模板。例如:我想转到{bar}。”

I want to have: 我希望有:

"Write {bar} to output the template. Example: I want to go to CHILE." “写{bar}以输出模板。例如:我想去智利。”

You can't do this in a single regex. 您不能在单个正则表达式中执行此操作。 First use 初次使用

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

to match {bar} only if there are no further braces around it. 仅在没有括号时才匹配{bar} Ie

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

will return 将返回

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

Then do a normal search-and-replace to replace {{ with { and }} with } . 然后进行常规搜索和替换,将{{替换为{}}并替换为}

You could use two regular expressions, one to look for the double-braced items and another for the single-braced ones. 您可以使用两个正则表达式,一个用于查找双括号项目,另一个用于单括号项目。 Alternatively, a callback could be used to determine the replacement value with just one regular expression. 或者,可以使用回调函数仅用一个正则表达式来确定替换值。

Separate patterns 分开的图案

$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
);

Single pattern with callback 带有回调的单一模式

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

Finally, are you doing this for one hard-coded labels (always bar ) or will the label part be a key for some varying replacement string? 最后,您是对一个硬编码标签执行此操作(始终为bar ),还是将标签部分作为替换字符串的键?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM