【问题标题】:preg_match_all in php produces different results with database stringphp 中的 preg_match_all 使用数据库字符串产生不同的结果
【发布时间】:2013-04-16 07:10:03
【问题描述】:

我在 php 中使用 preg_match_all 从用 DSL 编写的字符串构造标记。当我将测试字符串硬编码到我的 PHP 代码中并运行它时,一切正常。但是,当我从数据库中读取相同的字符串时,它匹配前两个标记,然后字符串的其余部分作为一个标记匹配,当它显然应该分成多个子单元时,就像字符串被硬编码时所做的那样。

这怎么可能?

我在正则表达式中使用 .+ 来匹配“其余部分”。基本上我的 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

【问题讨论】:

  • 可能是字符编码问题?
  • 可能,我该如何检查?
  • 从数据库中读取字符串,然后将其与您的硬编码字符串进行比较。

标签: php regex preg-match-all pcre


【解决方案1】:
(?P<Rest>.+(?=Keyword1)|.+(?=Keyword2)|.+(?=Keyword3)|.+)

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

现在,如果你将它们设为lazy,这应该有预期的输出:

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

编辑:
还应该检查 \v:

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

【讨论】:

  • 当我用你的正则表达式替换它时,它不再匹配其余的。只有关键字,很少有“休息”。
  • 你能举个例子吗?那会更容易测试。
  • 这是一个示例字符串:pastebin.com/qS5Qaqhh 它省略了“Test Talk”,但找到了其他所有内容。但对于许多其他字符串,它仍然有效。
  • @user975561 新行有问题。编辑这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-21
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多