2012-07-12 37 views
1

我想匹配/替换PHP中使用正则表达式如下输入文本:PHP preg_replace_callback正则表达式匹配失败

{#var1>var2} 
    {#>empty}inside empty{#>empty} 
    before rows 
    {#>firstrow}inside firstrow{#>firstrow} 
    {#>row}inside row{#>row} 
    {#>lastrow}inside lastrow{#>lastrow} 
    after rows 
{#} 

其中VAR1> VAR2是一个数组:

$var1['var2'] = array('key1' => 'value1', 'key2' => 'value2', ...) 

我有以下类与正则表达式(使用preg_replace_callback)来解析文本:

class parse { 

    public static function text($text) { 
    $text = preg_replace_callback('/\{(#+)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)((?:\>[a-zA-Z0-9_\x7f-\xff]*)*)\}\s*(\{\1\>empty\}\s*(.*?)\s*\{\1\>empty\})?\s*(.*?)\s*(\{\1\>firstrow\}\s*(.*?)\s*\{\1\>firstrow\})?\s*(\{\1\>row\}\s*(.*?)\s*\{\1\>row\})?\s*(\{\1\>lastrow\}\s*(.*?)\s*\{\1\>lastrow\})?\s*(.*?)\s*\{\1\}/s', array('parse', 'replace_array'), $text); 
    return $text; 
    } 

    public static function replace_array($matches) { 
    print_r($matches); 
    } 
} 

我得到的(不正确)输出:

Array (
    [0] => {#var1>var2>var3} {#>empty}inside empty{#>empty} before rows {#>firstrow}inside firstrow{#>firstrow} {#>row}inside row{#>row} {#>lastrow}inside lastrow{#>lastrow} after rows {#} 
    [1] => # 
    [2] => var1 
    [3] => >var2 
    [4] => {#>empty}inside empty{#>empty} 
    [5] => inside empty 
    [6] => 
    [7] => 
    [8] => 
    [9] => 
    [10] => 
    [11] => 
    [12] => 
    [13] => before rows {#>firstrow}inside firstrow{#>firstrow} {#>row}inside row{#>row} {#>lastrow}inside lastrow{#>lastrow} after rows 
) 

当我删除“前行”,从输入文本,我得到正确的结果:

Array (
    [0] => {#var1>var2>var3} {#>empty}inside empty{#>empty} {#>firstrow}inside firstrow{#>firstrow} {#>row}inside row{#>row} {#>lastrow}inside lastrow{#>lastrow} after rows {#} 
    [1] => # 
    [2] => var1 
    [3] => >var2 
    [4] => {#>empty}inside empty{#>empty} 
    [5] => inside empty 
    [6] => 
    [7] => {#>firstrow}inside firstrow{#>firstrow} 
    [8] => inside firstrow 
    [9] => {#>row}inside row{#>row} 
    [10] => inside row 
    [11] => {#>lastrow}inside lastrow{#>lastrow} 
    [12] => inside lastrow [13] => after rows 
) 

我已经寻找了一天,我认为这将是一个有点愚蠢的问题,但我找不到它......任何帮助?

+0

我有一个解决方案,但我仍然不知道为什么这个作品和以前的正则表达式没有...... 我换成'(\ {\ 1 \>行\} \ S * (。*?)\ s * \ {\ 1 \> row \})?'with'\ {\ 1 \> row \} \ s *(。*?)\ s * \ {\ 1 \ }' 有谁知道为什么这个正则表达式像这样? – WSas 2012-07-15 23:05:14

回答

0

这个工作对我来说:

\{(#+)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)((?:\>[a-zA-Z0-9_\x7f-\xff]*)*)\}\s*(\{\1\>empty\}\s*(.*?)\s*\{\1\>empty\})?\s*([^\n]*)\s*(\{\1\>firstrow\}\s*(.*?)\s*\{\1\>firstrow\})?\s*(\{\1\>row\}\s*(.*?)\s*\{\1\>row\})?\s*(\{\1\>lastrow\}\s*(.*?)\s*\{\1\>lastrow\})?\s*(.*?)\s*\{\1\} 

据我可以告诉(和它真的很难说),问题是这部分

{\1\>empty\})?\s*(.*?)\s* 

特别是(.*?) 不会匹配before rows,因为您使用的是\s标志。由于它不是贪婪,因此.将停止在第一场比赛,在这种情况下是换行符。

我所做的就是将其替换为:

{\1\>empty\})?\s*([^\n]*)\s* 

基本上是告诉它给我的一切,但换行,因为我真的不能在这里使用点运算符。

不确定我的推理是否100%正确,但我的模式应该如您在这里看到的那样工作。

http://regex101.com/r/dS4fG9