4

在 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?

4

4 回答 4

1

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

只要您不将选项嵌入其他选项中,这应该可以工作。

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带有示例输入的 ed 输出如下所示:

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"
  }
}
于 2013-02-05T19:50:45.413 回答
0

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

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

请注意 - 我假设您只有 1 对括号里面,并且在那对里面您只有 1 个字母数字字符

于 2013-02-05T18:54:14.737 回答
0

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

\{(option:)\S*\}

给定您的输入文本,以下条目在正则表达式中匹配:

测试 1

{blabla:数据库{测试}}

{blabla:测试}

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

{option:third{C}.Value}

{选项:第四{D}}

{选项:第五}

测试 2

于 2013-02-05T18:53:21.430 回答
0

如果您在同一级别上没有多对括号,则应该可以

/(\{option:(([^{]*(\{(?>[^{}]+|(?4))*\})[^}]*)|([^{}]+))\})/imsx
于 2013-02-05T19:40:47.573 回答