【问题标题】:What does this Regular Expression do这个正则表达式有什么作用
【发布时间】:2010-09-25 21:16:33
【问题描述】:
$pee = preg_replace( '|<p>|', "$1<p>", $pee );

这个正则表达式来自Wordpress源代码(formatting.php,wpautop函数);我不确定它的作用,有人可以帮忙吗?

实际上我正在尝试将此函数移植到 Python...如果有人已经知道现有端口,那会好得多,因为我对正则表达式真的很不好。

【问题讨论】:

  • 在这个 $1 可以引用的同一范围内是否有以前的匹配项?

标签: php regex wordpress


【解决方案1】:

preg_replace() 函数 - 有点令人困惑 - 允许您使用除标准“/”之外的其他分隔符用于正则表达式,所以

"|<p>|"

将是一个匹配的正则表达式

"<p>" 

在正文中。但是,我不清楚

的替换参数是什么
"$1<p>" 

会这样做,因为没有分组可以映射到 $1。看起来就像给定的,这只是用一个空字符串替换一个段落标记,然后是一个段落标记,实际上什么都不做。

对 PHP 怪癖有更深入了解的人有更好的分析吗?

【讨论】:

  • 这并不是 preg_replace 所独有的 - '/' 不是标准,它只是流行的约定。我实际上想不出一个强制你使用 / 的正则表达式实现
  • 嘿。除了 / 用于 Perl、Python、Java 或任何其他语言之外,我从未见过任何其他语言。我的理解是,这是在 PHP 中完成的,只是为了避免正则表达式的丑陋,可能包括在其中包含 / 的 HTML 标记。
  • @Jay:preg 函数使用 PCRE 库处理... Perl 兼容正则表达式。毫不奇怪,Perl 可以使用 / 以外的字符,所以 preg 也可以。
  • 我会说选择适合您要查找的内容的分隔符是非常标准的做法。如果您正在使用带有大量正斜杠的路径做事,那么正则表达式中的斜杠只是钝的。
【解决方案2】:

wordpress 真的调用了一个变量“pee”?

我不确定 $1 代表什么(第一个参数中没有大括号?),所以我认为它实际上没有任何作用,但我可能是错的。

【讨论】:

  • 确实如此。实际上,代码中有一条注释://不要在标签上撒尿
【解决方案3】:

...?

实际上,这看起来像使用第一个&lt;p&gt; 标记并将前一个正则表达式的第一个匹配项添加到它之前(因为这个匹配项中没有匹配项),

但是,至少可以说这种行为是不好的,因为无法保证 preg_* 函数不会用自己的值破坏 $1。

编辑:从 Jay 的评论来看,这个正则表达式实际上什么也没做。

【讨论】:

  • 我认为 preg_replace 不会将 $1 的反向引用带到 preg_replace() 的下一次调用中。我尝试了一个快速测试,但它似乎并没有那样工作。您仍然可能是对的,但如果是这样,那肯定是一种糟糕的做法!
  • 我没有在工作中测试它,因为我们这里没有安装 PHP……我想我可以在我自己的 Web 服务器上远程测试它。
【解决方案4】:

在这种情况下,管道符号| 没有“匹配这个或那个”的默认含义,而是用作模式的替代分隔符,而不是更常见的斜杠/。如果您想匹配/ 而不必逃避这些外观(例如/(.\*)\/(.\*)\// 不如#/(.\*)/(.\*)/# 可读性强),这可能是有道理的。不过,使用 | 似乎是相当有效的,这只是模式的另一个保留字符。

通常,替换模式中的$1 应该匹配括号中的第一组。例如,如果你有这样的模式

"(.*)<p>"

$0 将包含整个匹配项,$1 将包含 &amp;lt;p&amp;gt; 之前的部分。

由于给定的 reg-ex 没有声明任何组,并且 $1 不是在别处定义的变量(在 PHP4 中)的有效名称,因此此调用似乎将任何出现的 &amp;lt;p&amp;gt; 替换为 &amp;lt;p&amp;gt;

说实话,现在我也很困惑。只是一个猜测:在给定行之前调用另一个模式匹配方法(preg_match 等),所以 $1 从那里“泄漏”?

【讨论】:

  • 我通过对 preg_replace 的示例调用测试了该理论,但我无法从之前的调用中获得 $1 来引用。所以看起来也不是这样,除非它是特定 PHP 版本的怪癖?
【解决方案5】:

我强烈推荐惊人的RegexBuddy

【讨论】:

  • 这可能对这个特定问题没有帮助,因为有问题的代码不是标准的正则表达式问题。分隔符是非标准的,并且反向引用实际上并不来自模式内,因此 RegexBuddy 可能也无法破译这一点。
  • 虽然我同意你的观点,但 RegexBuddy 有一些选项可以显示 Regex 在几种语言中的实现差异,这对他来说可能很方便,因为他正在尝试将其从 php 移植到 python。跨度>
  • RegexBuddy 确实会表明这个搜索和替换什么都不做。非标准分隔符没有问题。只需在粘贴菜单中选择“Paste from PHP preg string”,RegexBuddy 就会弄清楚。 $1 反向引用被简单地替换为没有,RegexBuddy 也模拟了。
【解决方案6】:

我相信那条线什么都不做。

对于它的价值,这是前一行,其中设置了 $1:

$pee = preg_replace('!<p>([^<]+)\s*?(</(?:div|address|form)[^>]*>)!', "<p>$1</p>$2", $pee);

但是,我认为这不值得。在我的测试中,$1 不会保持从一个 preg_replace 到下一个的值,即使下一个没有为 $1 设置自己的值。请记住,PHP 变量名称不能以数字开头(请参阅:http://php.net/language.variables),因此 $1 不是 PHP 变量。它仅表示单个 preg_replace 中的某些内容,在这种情况下 preg_replace 的规则表明它没有任何含义。

也就是说,autop 是一个如此广泛使用的函数,这让我怀疑我自己的结论,即这条线什么也没做。所以我期待有人纠正我。

【讨论】:

  • 在我的网络服务器上测试后,我得出了同样的结论。希望有人能过来确认或否认;)
  • PHP 的 preg 函数不像 Perl 和 Ruby 那样设置魔法变量。 $1 在 PHP 中不作为变量存在。
【解决方案7】:

正则表达式只匹配文字文本

。选择用竖线而不是正斜杠来分隔正则表达式是非常不幸的。它不会更改代码,但会使人类更难阅读。 (这也使得在正则表达式中无法使用交替运算符。)

$1 在 PHP 中不是一个有效的变量名,因此 $1 永远不会插入双引号字符串中。 $1 不变地传递给 preg_replace。 preg_replace 解析替换字符串,并将 $1 替换为第一个捕获组的内容。如果没有捕获组,$1 将被替换为空。

因此,此代码的作用与以下相同:

$pee = preg_replace( '/<p>/', "<p>", $pee );

这不做任何事情是不正确的。搜索和替换将运行,降低您的软件速度,并为 $pee 的临时副本占用内存。

【讨论】:

    【解决方案8】:

    我对 RegEx 没有太多经验,我的 atm 上没有 RegEx 测试工具,但是在搜索并查看了其他 WordPress 源代码和 cmets 之后,这段代码是否有可能删除重复的段落标签和用一组标签替换它们。

    【讨论】:

    • 也这么认为 - 但是 preg_replace 匹配主题中出现的任何 p-Tag 并用替换模式替换它(所以 foo[p][p]bar 保持 foo[p][p]酒吧)
    【解决方案9】:

    它从模式中替换匹配

    "|<p>|" 
    

    通过字符串

    "$1<p>"
    

    该 |在替换模式中是导致正则表达式引擎匹配左侧的部分或右侧的部分。

    我不明白为什么会这样使用它,因为通常它是用于“ta(b|p)e”之类的...

    对于 $1,我猜变量 $1 在 PHP 代码中,它在 preg_replace 期间被替换,所以 if $1 = "test";替换将替换

    "<p>" 
    

    "test<p>"
    

    但对于 1 美元我不确定

    【讨论】:

    • $1 将是非法变量名,因此不能在代码中设置。它必须是 preg_replace() 中正则表达式的反向引用,除非正则表达式中没有任何组,所以它应该只是一个空字符串。
    猜你喜欢
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多