模式不逃避字符

时间:2012-03-21 16:12:56

标签: php regex pcre

我有这种模式,我使用preg_match,我无法弄清楚我哪里出错了。

$pattern = "{(\[fn:)([0-9]*)(\])((?:\\\[|[^\[])*)}";

它必须匹配每个 [fn:i] text_multiline ,直到另一个开始,所以当它遇到 [并且我想要逃脱 [ >通过以下示例中的 \ [

  

[fn:1]这是\ [这需要转义]脚注1的文字。

     

请注意,它可能是多个段落。

     

[fn:2]这是脚注2的文字。

这是我目前得到的比赛:

array(5) {
  [0]=>
  string(6) "[fn:1]"
  [1]=>
  string(4) "[fn:"
  [2]=>
  string(1) "1"
  [3]=>
  string(1) "]"
  [4]=>
  string(0) ""
}

2 个答案:

答案 0 :(得分:2)

当你想要排除和转义时使用的技术[被称为“负面看后面”。

例如,

(?<!\\)\[

此正则表达式将匹配[但忽略它是否由\

继续

如果您需要更多帮助,请告诉我

编辑#1

这是适用于您的特定情况的负面观察

\[fn:\d+](?:\\\[|[^[])*

并在php中变为

if (preg_match('/\[fn:\d+\](?:\\\\\[|[^[])*/', $subject)) {
    # Successful match
} else {
    # Match attempt failed
}

一些注释

  • 我使用轮换并让它首先匹配转义[因此它不会被交替后的匹配排除(依赖于交替顺序的常见技巧)
  • 我从头开始,所以如果你需要捕获一些组,那么在需要的地方添加括号
  • 构造(?:)用于分组但不捕获。这(也许)更有效率,正如我所说的那样,我省略了捕获

正则表达式针对您的示例进行了测试。如果你能让它现在正常工作,请告诉我

祝你好运,巴克利

答案 1 :(得分:0)

preg_replace_all("#\\[(?!fn:\\d+\\])#", "\\[")会做到这一点,但最好不要使用正则表达式。