分析器替换模式

时间:2011-10-04 13:55:25

标签: php parsing design-patterns

我有模式问题。 我需要处理一些文本,例如:

<div>{text1}</div><span>{text2}</span>

在这个过程之后,我需要从字典中取代{text1}和{text2}一些单词。 我正在为不同语言准备ui界面。 这是用PHP。现在我有类似的东西,但这不起作用:

function translate_callback($matches) {
  global $dict;
  print_r($matches);
  return 'replacement';
}

function translate($input) {
  return preg_replace_callback('/(\{.+\})/', 'translate_callback', $input);
}

echo translate('<div>{bodynum}</div><span>{innernum}</span>');

这是测试方案,但我无法找到定义模式的方法,因为这个代码匹配

{bodynum}</div><span>{innernum}

但我想要匹配的模式

{bodynum} and then {innernum}

有人可以帮我这个吗?感谢。

解决方案:

匹配{和}之间的任何字符,但不要贪婪 - 匹配以}结尾的最短字符串(停止+贪婪)。

所以这个模式现在看起来像是:'/ {(+ +?)} /'并且非常符合我的要求。

3 个答案:

答案 0 :(得分:0)

您应该在模式中使用“U”修饰符。 More

答案 1 :(得分:0)

尝试

// this will call my_callback() every time it sees brackets  
$template = preg_replace_callback('/\{(.*)\}/','my_callback',$template);  

function my_callback($matches) {  
    // $matches[1] now contains the string between the brackets  

    if (isset($data[$matches[1]])) {  
        // return the replacement string  
        return $data[$matches[1]];  
    } else {  
        return $matches[0];  
    }  
}

<强> Reference

答案 2 :(得分:0)

正如您在评论中正确注意到的那样,您可以使用ungreedy match来停止在第一个右括号而不是最后一个:

preg_replace_callback('/(\{.+?\})/', 'translate_callback', $input);

正如Damien所说,你也可以使用/U修饰符默认使所有匹配都不合适。

或者,您可以将大括号之间允许的字符集限制为不包含}的某些字符集:

preg_replace_callback('/(\{[^}]+\})/', 'translate_callback', $input);

甚至:

preg_replace_callback('/(\{\w+\})/', 'translate_callback', $input);

在大括号之间只允许word characters。由于PCRE引擎的工作方式,这可能(或可能不)比使用不合理匹配稍微更有效。当然,在实践中,不太可能存在任何可观察到的差异。