2012-03-21 32 views
1

我有这种模式,我与preg_match一起使用,我无法确定我出错的地方。模式不转义字符

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

它具有以匹配每个[FN:I] text_multiline直到另一个开始,从而当它满足[,我想escapte的[通过\ [从下面的例子:

[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) "" 
} 
+0

你的分隔符必须匹配。你不能使用'{'和'} – AndrewR 2012-03-21 16:15:21

+1

我真的不认为这是问题所在。我以前使用过这个分隔符的模式,它工作正常。 – 2012-03-21 16:16:50

+1

嗯,我想那些是有效的分隔符。我不知道这会起作用。 :) – AndrewR 2012-03-21 16:19:08

回答

2

当你想排除和逃避时使用的技术[称为“负面看”。

例如,

(?<!\\)\[ 

此正则表达式匹配[却忽略了如果由\

继续让我知道如果你需要更多的帮助

编辑#1

这是适用于您的特定场景的负向后视

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

,并在PHP中,这成为

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

的一些注意事项

  • 我用交替,让它先匹配逃脱[所以它不会被轮换后所匹配排除(常见的技巧依赖于交替的顺序)
  • 我从头开始,所以如果你需要捕获一些组,然后在需要的地方添加括号
  • 构造(?:)用于分组但不捕获。这是(可能)更高效,正如我说的,我省略了捕获

正则表达式针对您的示例进行了测试。让我知道如果你现在可以得到它

祝你好运,巴克利

+0

我无法设法将其整合到原始模式中。我试过**“{(\ [fn:)([0-9] *)(\])(((?<!\\)\ [)*)}”** and **“{( \ [fn:)([0-9] *)(\])((?<!\\)\ [*)}“** – 2012-03-21 16:38:46

+0

它应该在lookbehind中有四个反斜杠。 PHP的字符串标记器消耗了一个级别的转义。 – mario 2012-03-21 16:50:24

+0

@mario你能帮我解决吗。我仍然无法弄清楚这个问题 – 2012-03-21 17:54:27

0

preg_replace_all("#\\[(?!fn:\\d+\\])#", "\\[")会做的伎俩,但最好不要为此使用正则表达式。