【问题标题】:preg_match_all has different result set than preg_replace using the same patternpreg_match_all 的结果集与使用相同模式的 preg_replace 不同
【发布时间】:2017-09-12 17:53:09
【问题描述】:

我发现 preg_match_all 和 preg_replace 找不到基于相同模式的相同匹配项。

我的模式是:

/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\1)>/

当我对一个包含

之类的 sn-p 运行它时
<span class="blue"></span> 

使用 preg_match_all 我得到 17 个匹配项。

当我在 preg_replace 中使用相同的模式时,我得到 0 个匹配项。用选择列表替换 \1 确实会找到匹配项,但当然这不会作为解决方案起作用,因为它不能确保结束标记与开始标记的类型相同。

总体目标是找到没有内容的标签实例,这些标签不应该在没有内容的情况下出现......我向你保证,这是一场神圣的十字军东征。

在测试正则表达式是否有效时,我也在 php cli 中尝试过。这是输出:

Interactive shell

php > $str = 'abc<span class="blue"></span>def';
php > $pattern = "/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\1)>/";
php > $final = preg_replace($pattern, '', $str);
php > print $final;
abc<span class="blue"></span>def

【问题讨论】:

  • (.*?) 似乎总是会导致问题。将其更改为: ([^>]+) 表示至少 1 不大于。如果可行,请告诉我,我会写一个更完整的答案。
  • 如果我理解正确,我将模式更改为: "/]+)>/i" 导致没有 preg_match_all火柴。我注意到它在标签中需要标签名称以外的东西,不一定是这种情况,可能只是 ,所以我将其更改为 "/ ]*)>/i" 但仍然没有匹配项。
  • za̡͊͠͝lgό,h̸̡̪̯ͨ͊̽̅̾ȩ̸̡̬̩̪̯̾͛ͪ̈ͨ͊̽̅̾͘ȩ̬̩̾͛ͪ̈͘c̷̙̝͖ͭ̏ͥͮ͟oͮ͏̮̪̝͍m̖͊̒ͪͩͬ̚̚͜ȇ̴̟̟͙̞ͩ͌͝səstackoverflow.com/questions/1732348/… span>
  • 非常有趣,但如果我用一些随机分隔符替换尖括号从而使其不是 HTML ,那么这将是一个问题,所以不是很有帮助:-)
  • 不正确,我的朋友,你得到 17 个匹配的原因是因为你写了一个依赖 html 结构的正则表达式,并以你不想要的方式匹配它。您正在尝试使用正则表达式搜索 DOM,这是邪恶和错误的。查看我的答案以获得成熟的解释。

标签: php regex preg-replace preg-match-all


【解决方案1】:
$str = 'abc<span class="blue"></span>def';
$pattern = "/<(title|h1|h2|h3|h4|h5|ul|ol|p|figure|caption|span)(.*?)><\/(\\1)>/";
                                                              // added \  ^
$final = preg_replace($pattern, '', $str);
print $final;
// echos 'abcdef'

解释:

"\1" // <-- character in octal notation

很不一样
'\1' // <-- backslash and 1

因为第一个是转义序列。这也是我几乎只使用单引号字符串的原因。见http://php.net/string#language.types.string.syntax.double

【讨论】:

  • 这行得通!我是否正确地阅读了您的更改转义了反斜杠,而不是转义了 1?
  • 补充说明
  • 尝试使用 php -a: echo '\1';echo "\1";
  • 对于您的问题:是的,添加的反斜杠转义了反斜杠;o)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-01
  • 2021-10-27
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
相关资源
最近更新 更多