2013-02-05 204 views
3

在PHP中,我有以下字符串:PHP:正则表达式匹配完整的匹配括号?

$text = "test 1 
      {blabla:database{test}} 
      {blabla:testing} 
      {option:first{A}.Value}{blabla}{option:second{B}.Value} 
      {option:third{C}.Value}{option:fourth{D}} 
      {option:fifth} 
      test 2 
     "; 

我需要得到所有{option ...}出这个字符串(5总共在这个字符串)。有些在其中有多个嵌套括号,有些则没有。有些是在同一条线上,有些则不是。

我已经发现了这个正则表达式:

(\{(?>[^{}]+|(?1))*\}) 

所以下面的工作正常:

preg_match_all('/(\{(?>[^{}]+|(?1))*\})/imsx', $text, $matches); 

,这不是大括号内的文字被过滤掉了,但比赛还包括blabla -items ,我不需要。

有什么办法可以修改这个正则表达式,只包含option -items?

+0

这听起来像一个文法分析工作。我有一次相关的问题。我很好奇,如果有人能完成这项工作! :) – hek2mgl

+0

可以有多少个嵌套大括号? – Flosculus

+1

[我对另一个问题的回答可能对你有用](http://stackoverflow.com/a/11468459/599857) – Leigh

回答

0

我修改了您的初始表达式以搜索附加了非空白字符(\ S *)的字符串'(option :)',并由大括号'{}'限制。

\{(option:)\S*\} 

鉴于你输入的文字,下面的条目在regexpal匹配:

测试1

{布拉布拉:数据库{测试}}

{布拉布拉:测试}

{option:first {A} .Value}{option:second {B} .Value}

{选项:第三{C}。价值}

{选项:第四{d}}

{选项:第五}

试验2

+0

工作正常,但Leigh的答案也适用于A和B选项之间没有空格时,所以我选择了一个作为答案。 – Dylan

0

试试这个正则表达式 - 它使用.NET正则表达式进行测试,它也可以与PHP一起使用:

\{option:.*?{\w}.*?} 

请注意 - 我假设你只有1对括号内,而且对里面你只有1字母数字字符

0

如果你没有在同一个多对括号水平这应该工作

/(\{option:(([^{]*(\{(?>[^{}]+|(?4))*\})[^}]*)|([^{}]+))\})/imsx 
0

这个问题是更适合适当的解析器,但是你可以用正则表达式,如果你真的想。

只要您没有在其他选项中嵌入选项,这应该工作。

preg_match_all(
    '/{option:((?:(?!{option:).)*)}/', 
    $text, 
    $matches, 
    PREG_SET_ORDER 
); 

快速说明。

{option:    // literal "{option:" 
    (     // begin capturing group 
    (?:    // don't capture the next bit 
     (?!{option:). // everything NOT literal "{option:" 
    )*     // zero or more times 
)     // end capture group 
}      // literal closing brace 

var_dump与样品输入输出编样子:

array(5) { 
    [0]=> 
    array(2) { 
    [0]=> 
    string(23) "{option:first{A}.Value}" 
    [1]=> 
    string(14) "first{A}.Value" 
    } 
    [1]=> 
    array(2) { 
    [0]=> 
    string(24) "{option:second{B}.Value}" 
    [1]=> 
    string(15) "second{B}.Value" 
    } 
    [2]=> 
    array(2) { 
    [0]=> 
    string(23) "{option:third{C}.Value}" 
    [1]=> 
    string(14) "third{C}.Value" 
    } 
    [3]=> 
    array(2) { 
    [0]=> 
    string(18) "{option:fourth{D}}" 
    [1]=> 
    string(9) "fourth{D}" 
    } 
    [4]=> 
    array(2) { 
    [0]=> 
    string(14) "{option:fifth}" 
    [1]=> 
    string(5) "fifth" 
    } 
} 
+0

嗨Leigh,仍然存在一个小问题:如果两个选项之间存在{...},则{...}部分包含在匹配中。 (请参阅修改的示例文本)以任何方式避免这种情况? – Dylan

+0

@Dylan它可以使用递归完成。请参阅我最初在评论中与您的问题相关的答案。你应该能够适应这一点。 – Leigh