【问题标题】:Expression with multiple { } blocks具有多个 { } 块的表达式
【发布时间】:2012-04-30 11:00:58
【问题描述】:

我正在尝试创建一个匹配任何这些文本的正则表达式(在 PHP 中):

#{text}
#{text1}{text2}
#{text1}{numbers}{text2}
#{text1}{text with spaces}{numbers}{text2}

等等。基本上第一个块只能容纳没有空格的文本,而其余的可以容纳任何东西。在那之后,得到匹配那些文本1...数字等。我一直在尝试一些正则表达式,但它没有成功。这是最后一个:

/#{(\w+)}({([\ a-zA-Z0-9*])})*/U

提前致谢!

编辑:就像@stema 建议的那样,我将我的正则表达式更改为这个:

/#\{(\w+)\}(\{([^}]*)\})*/

我避免使用 Ungreedy 标志,因为它根本没有帮助表达:)。但是,结果并没有我需要的那么多:

array(4) {
  [0]=>
  string(42) "#{text1}{text with spaces}{numbers}{text2}"
  [1]=>
  string(5) "text1"
  [2]=>
  string(7) "{text2}"
  [3]=>
  string(5) "text2"
}

似乎中间参数没有被解析(这对我来说很奇怪)。

【问题讨论】:

  • 它失败了:当试图解析最后一个例子(有 4 个块)时,我得到了这些匹配:#{text1} 和 text1
  • 看来您只是在计算第二个大括号内的一个字符 {([\ a-zA-Z0-9*])} 应该类似于 {([\ a-zA-Z0-9*]+)}

标签: php regex


【解决方案1】:

我看到的主要问题是量词放错了位置

/#{(\w+)}({([\ a-zA-Z0-9*])})*/U
                        ^

应该在字符类之外

/#{(\w+)}({([\ a-zA-Z0-9]*)})*/U

如果以下大括号中的内容可以是任何内容,那么您可以这样做

/#\{(\w+)\}(\{([^}]*)\})*/U

[^}] 是一个否定字符类,它匹配除了右大括号之外的任何字符。

我也省略了花括号,因为它们作为量词的一部分具有特殊含义。一些语言在它们没有形成这样的量词时会按字面意思匹配它们,但为了清楚起见,最好在应该匹配它们时始终将它们转义。

更新:

您可以将其中一个组设为非捕获组,因为您似乎不需要它

/#\{(\w+)\}(?:\{([^}]*)\})*/

这应该会给你这个结果

array(4) {
  [0]=>
  string(42) "#{text1}{text with spaces}{numbers}{text2}"
  [1]=>
  string(5) "text1"
  [2]=>
  string(5) "text2"
}

但您将始终只获得结果数组中重复组的最后一个匹配项,因为每个匹配项都存储在array[2]。第二场比赛将覆盖第一场比赛,第三场比赛将覆盖第二场......

您可以做的是使用正则表达式进行格式验证,然后进行拆分,例如像这样的

$in = "#{text1}{text with spaces}{numbers}{text2}";
$result = preg_split('/}{|#{|}/', $in, -1, PREG_SPLIT_NO_EMPTY);

【讨论】:

  • +1。我也会逃脱大括号。并非所有的正则表达式引擎都足够聪明,可以从上下文中推断出它们在这里不是量词,并且会在编译时引发错误。
  • 谢谢蒂姆,我已将其添加到我的答案中。
  • 你可以使用+而不是*来避免第一个块
  • @dresende 不,因为第一个块可以包含与以下不同的字符。
  • @stema 说的是正确的。顺便说一句,我稍微编辑了我的问题
【解决方案2】:

按照stema的回答,我建议

  1. 使用正则表达式验证字符串
  2. 因为您不能为此目的使用捕获组,所以我将删除前导 #{ 和尾随 } 然后 split 这个正则表达式上的字符串 }{

这应该会给你一个包含所有匹配项的数组。

【讨论】:

  • 非常感谢,@乔安娜!因为这个好主意,我也给你一个 +1。但是,@stema 的更完整,所以我不得不接受他的。
猜你喜欢
  • 2018-10-01
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多