2013-04-23 37 views
0

我在php中使用preg_match_all来构造写在DSL中的字符串的标记。当我将测试字符串硬编码到我的PHP代码中并运行它时,它都可以工作。但是,当我从数据库中读取相同的字符串时,它会匹配前两个标记,然后将其余的字符串匹配为一个标记,当清楚地将其拆分为多个子单元时,就像字符串被硬编码时一样。php中的preg_match_all产生与数据库字符串不同的结果

这怎么可能?

我正在使用。+在我的正则表达式中匹配“其余”。基本上我的DSL包括关键字和休息,所以我对preg_match_all正则表达式如下:

/(?P<NameOfKeyword1>Keyword1)|(?P<NameOfKeyword2>Keyword2)|(?P<NameOfKeyword3>Keyword3)|(?P<Linebreak>\\v+)|(?P<Rest>.+(?=Keyword1)|.+(?=Keyword2)|.+(?=Keyword3)|.+)/ 

基本上,我的第一场比赛的关键词,然后我匹配换行符,那么剩下的,直到下一个关键字(或断行或结束的字符串)出现。

那么为什么它在字符串硬编码时正确匹配,但是当从数据库中读取相同的字符串时不能正确匹配?

当从数据库中读取匹配为一个标记的字符串的其余部分时,不应该将其作为一个标记进行匹配,因为它们之间有关键字。它看起来像它匹配它基于+

编辑: 我使用的preg_match_all的标志是PREG_SET_ORDER和PREG_OFFSET_CAPTURE

+0

也许字符编码问题? – Barmar 2013-04-23 07:37:57

+0

可能,我该如何检查? – user975561 2013-04-23 08:07:36

+0

从数据库中读取字符串,然后将其与硬编码字符串进行比较。 – Barmar 2013-04-23 08:27:27

回答

1
(?P<Rest>.+(?=Keyword1)|.+(?=Keyword2)|.+(?=Keyword3)|.+) 

这并不意味着“那么剩下的,直到下一个关键字(或换行或字符串结束)出现。“。事实上,除了新线以外,它永远不会停止。
为什么?你正在使用lookaheads。基本上,.(?=Keyword1)的意思是“任何字符后跟Keyword1”(+它只是表示“一系列字符,每个字符都跟着Keyword1”)。
所以那些不会匹配任何东西。最后的.+是其余完全匹配的原因。

现在,如果你让他们lazy,这应该有预期的输出:

(?P<Rest>.+?(?=Keyword1|Keyword2|Keyword3|$)) 

编辑:
还应该检查\五:

/(?P<NameOfKeyword1>Keyword1) 
|(?P<NameOfKeyword2>Keyword2) 
|(?P<NameOfKeyword3>Keyword3) 
|(?P<Linebreak>\v+) 
|(?P<Rest>.+?(?=Keyword1|Keyword2|Keyword3|\v|$))/ 
+0

当我用你的正则表达式替换它时,它不再与其他表达式匹配。只有关键字和很少的“休息”。 – user975561 2013-04-23 08:09:08

+0

你能举个例子吗?这将更容易测试。 – Loamhoof 2013-04-23 08:16:41

+0

下面是一个示例字符串:http://pastebin.com/qS5Qaqhh它遗漏了“Test Talk”,但发现了其他所有内容。对于很多其他的字符串,它可以工作。 – user975561 2013-04-23 09:05:24

相关问题