我试图更改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标签。
严肃的笔记!
使用正则表达式来解析/匹配 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;
正则表达式并不坏、邪恶或可怕,它们只是工作的错误工具,你不会用手提钻钉钉子吧?
$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上放开这样的东西是自找麻烦。
避免!避免!避免!
每个('w+)
都说找到一个单词并存储它。 所以你正在这样做(在伪代码中)
find /(word1) (word2)="(word3)" (word4)="(manypossiblechars5)"/ignoring case
replace pattern with $comStart.<word1 word2="word3:word4" manypossiblechars5="word6">.$comEnd
第一个尝试将表单<meta name="og:...
的标签替换为<meta property="og:...
第二个类似地将<meta name="fb:admins...
开头的标记替换为<meta property="fb:admins...
最后,第三个似乎采用<word word="word:word" word="something" '/>
形式的标签,并用$comStart
和$comEnd
包裹它们。
这是通过匹配标签的各个部分(在它们周围放置()
),然后使用反向引用(如 ${4}
)来引用第 4 个匹配部分来完成的。
在这里,$comStart
和$comEnd
设置为",所以这似乎有点毫无意义。它还设法同时摆脱了标签的右斜杠,尽管谁知道这是否是故意的!
这些表达式尝试通过以下方式修复文档头代码:
- 将
<meta name="og:*"
重写为 ' - 将
<meta name="fb:admins"
重写为<meta property="fb:admins"
将带有悬空斜杠的元标记 - 重写为没有斜杠的元标记(假设它始终具有两个属性。
这只是可怕的代码,只要你的模板没有 其中的那些"错误",你可以把这些废话扔掉。