0

我有两个字符串,最多包含 3 个元素:

1) anychar[price]{alphanum} e.g. a1\')[=00.00]{a1234}
2) anychar:anychar{alphanum} e.g. a1\'):a2\'){a1234}

...但 {} 元素是可选的,可能并不总是存在。我写了以下模式(分别):

1) /(.+)\[(.+)\]\{*(\w+)*\}*/- 按预期工作

2) /(.+)\:(.+)\{*(\w+)*\}*/- 如果 {} 元素被移除,但它不能正常工作。

2 的结果数组如下:

( [0] => a1\'):a2\'){a123} [1] => a1\') [2] => a2\'){a123} )

我已经尝试了上述几种不同的排列,但没有骰子。有任何想法吗?

4

1 回答 1

1

首先,您应该删除 {、} 和 (\w+) 之后的 *。

'/(.+)\:(.+)\{(\w+)\}/'

array(4) {
  [0]=>
  string(18) "a1\'):a2\'){a1234}"
  [1]=>
  string(5) "a1\')"
  [2]=>
  string(5) "a2\')"
  [3]=>
  string(5) "a1234"
}

* 表示 0、1 或多个,并且 PCRE 试图找到它可以找到的最快路线,因此如果您将整个第三部分设为可选(通过在任何地方使用 *),那么最快的路线是将所有内容都包含在第二组中并跳过第三,这就是你的代码不起作用的原因。

现在,为了处理第三部分是可选的这一事实,您必须使用积极的前瞻:在第二组中,您将要求 pcre 仅当它可以匹配其后的另一个正则表达式时才选择它。最终的正则表达式是这样的:

'/(.+)\:(.+(?=(?:(?<=[^}])$|\{(\w+)\})))/'

我改变的是:

  • 在第二组中,我以 (?=regex) 的形式添加了一个积极的前瞻。如前所述,这意味着它必须匹配。默认情况下,前瞻不是选择性的,这意味着它们不会在您的最终结果中创建条目/它们不会返回给您。

  • 在该前瞻中,我创建了两种情况,这意味着为了匹配,第二组中的 .+ 必须匹配我的前瞻中的任何一种情况。

  • 第一种情况非常基本,它表示字符串的结尾没有 },当第三部分不存在时,这将匹配字符串

  • 第二种情况,如果您选择第 3 组,我们将其设为可选,以便在结果中返回(如果存在)

于 2011-05-27T09:28:29.513 回答