1

我试图更改 joomla 插件的某些部分,当我面对它的这一部分时,我不知道它在做什么。

有人可以向我解释这些正则表达式的${4}作用吗?

    $comStart = '';
    $comEnd = '';

    $output = JResponse::getBody();
    $output = preg_replace('/\<meta name=\"og\:/', '<meta property="og:', $output);
    $output = preg_replace('/\<meta name=\"fb:admins/', '<meta property="fb:admins', $output);
    $output = preg_replace('/<(\w+) (\w+)="(\w+):(\w+)" (\w+)="([a-zA-Z0-9\ \_\-\:\.\&\/\,\=\!\?]*)" \/>/i', $comStart.'<${1} ${2}="${3}:${4}" ${5}="${6}" >'.$comEnd, $output);

仅供参考:此插件用于在文章中显示 facebook 和 opengraph 标签。

4

5 回答 5

3

严重注意!

强烈建议不要使用正则表达式来解析/匹配 HTML/XML。认真的不要做

基本上,它是解析/匹配 HTML 的正则表达式。这可能会产生不工作难以维护精神错乱的轻微副作用。

这些${N}称为反向引用,它们引用正则表达式中匹配的第 N 个括号。


如果你需要在 PHP 中处理 HTML 字符串,你应该使用DOMDocument专门为此而设计的类。

例子

<?php

$html_string = <<<HTML
<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>

  <div id="target">
    This is the target DIV! <span>This span will change texts!</span>
  </div>

</body>
</html>
HTML;

$dom = new DOMDocument();
// Loading HTML from string...
$dom->loadHTML($html_string);

//Retrieve target and span elements
$target = $dom->getElementById("target");
$span = $target->getElementsByTagName("span")->item(0);

//Remove text, firstChild is the text node.
$span->removeChild($span->firstChild);
//Append new text
$span->appendChild(new DOMText("This is the new text!"));
//Change an attribute
$span->setAttribute("class", "spanny");

//Save HTML to string
$html_string = $dom->saveHTML();

echo $html_string;

正则表达式不是坏的、邪恶的或可怕的,它们只是工作的错误工具,你不会用手提钻钉钉子吧?

于 2012-06-12T15:04:29.407 回答
3
$output = preg_replace('/\<meta name=\"og\:/', '<meta property="og:', $output);

<meta name="og:用替换字符串<meta property="og:。有点毫无意义——这里不需要正则表达式。

$output = preg_replace('/\<meta name=\"fb:admins/', '<meta property="fb:admins', $output);

替换<meta name="fb:admins<meta property="fb:admins。同样毫无意义 - 这里不需要正则表达式。

$output = preg_replace('/<(\w+) (\w+)="(\w+):(\w+)" (\w+)="([a-zA-Z0-9\ \_\-\:\.\&\/\,\=\!\?]*)" \/>/i', $comStart.'<${1} ${2}="${3}:${4}" ${5}="${6}" >'.$comEnd, $output);

<word1 word2="word3:word4" word5="word6withspecialcharacterslike-:.etc." />用替换字符串<word1 word2="word3:word4" word5=word6withspecialcharacterslike-:.etc." >。所以它只在关闭之前删除一个斜杠>。非常可疑和类似巫毒教的正则表达式使用。

此外,所有这些正则表达式都非常不优雅(例如,许多毫无意义的转义),并表明编写这些正则表达式的人对正则表达式知之甚少。在 HTML 上放这样的东西是自找麻烦。

避免!避免!避免!

于 2012-06-12T15:07:51.610 回答
2

每个(\w+)人都说找到一个单词并存储它。所以你正在这样做(在伪代码中)

find /(word1) (word2)="(word3)" (word4)="(manypossiblechars5)"/ignoring case

replace pattern with $comStart.<word1 word2="word3:word4" manypossiblechars5="word6">.$comEnd
于 2012-06-12T15:07:10.207 回答
2

第一个尝试将表单的标签替换<meta name="og:...<meta property="og:...

第二个类似地替换以开头<meta name="fb:admins...的标签<meta property="fb:admins...

最后,第三个似乎采用了表单的标签并用and<word word="word:word" word="something" \/>包裹它们。$comStart$comEnd

这是通过匹配标签的各个部分(放置()在它们周围)然后使用反向引用${4}来完成的,例如引用第 4 个匹配的部分。

这里$comStartand$comEnd都设置为 '' 所以这似乎有点毫无意义。它还设法同时摆脱了标签的结束斜线,但谁知道这是否是故意的!

于 2012-06-12T15:08:53.697 回答
2

这些表达式尝试通过以下方式修复文档头代码:

  1. 重写<meta name="og:*"为`
  2. 重写<meta name="fb:admins"<meta property="fb:admins"
  3. 将带有悬垂斜杠的元标记重写为没有它的一个(假设它总是有两个属性。

这只是可怕的代码,只要你的模板中没有那些“错误”,你就可以把这些废话扔掉。

于 2012-06-12T15:11:30.513 回答