这些正则表达式在此代码中意味着什么?

时间:2012-06-12 14:59:18

标签: php regex joomla preg-replace

我试图更改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标签。

5 个答案:

答案 0 :(得分:3)

  

严重注意!

     

使用正则表达式来解析/匹配HTML / XML非常重要   泄气。说真的,don't do it

基本上,它是解析/匹配HTML的正则表达式。这可能会产生轻微的副作用,无效难以维护 insanity

${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;

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

答案 1 :(得分: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." >。因此它只在结束>之前删除尾部斜杠。非常怀疑和Voodoo一样使用正则表达式。

此外,所有这些正则表达式都非常不优雅(例如,许多无意义的逃避),并表明写这些正则数据的人对正则表达式知之甚少。在HTML上放弃这样的东西会让人感到麻烦。

避免!避免!避免!

答案 2 :(得分:2)

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

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

replace pattern with $comStart.<word1 word2="word3:word4" manypossiblechars5="word6">.$comEnd

答案 3 :(得分:2)

第一个尝试将<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设置为'',因此这似乎有点无意义。它还设法同时摆脱标签的结束斜线,虽然谁知道这是否是故意的!

答案 4 :(得分:2)

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

  1. <meta name="og:*"重写为`
  2. <meta name="fb:admins"重写为<meta property="fb:admins"
  3. 使用悬挂斜线重写元标记到没有它的一个(假设它总是有两个属性。
  4.   

    这只是可怕的代码,只要你的模板没有   在他们身上的那些“错误”,你可以抛弃这个废话。