【问题标题】:find-and-replace-in-html regular expression failsfind-and-replace-in-html 正则表达式失败
【发布时间】:2010-06-29 08:59:04
【问题描述】:

我有一个正则表达式,它通过 html 内容查找一些曾经有效的关键字,但现在失败了,我不明白为什么。 (正则表达式来自this thread。)

$find = '/(?![^<]+>)(?<!\w)(' . preg_quote($t['label']) . ')\b/s';
$text = preg_replace_callback($find, 'replaceCallback', $text);

function replaceCallback($match) {
        if (is_array($match)) {
            $htmlVersion = $match[1];
            $urlVersion = urlencode($htmlVersion);
            return '<a class="tag" rel="tag-definition" title="Click to know more about ' . $htmlVersion . '" href="?tag=' . $urlVersion . '">' . $htmlVersion . '</a>';
        }
        return $match;
    }

错误消息指向 preg_replace_Callback 调用并说:

Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier 't' in /frontend.functions.php  on line 43

【问题讨论】:

标签: php html regex


【解决方案1】:

请注意:这不是试图为正则表达式提供修复。它只是在这里展示创建一个能够成功解析 HTML 的正则表达式是多么困难(我敢说不可能)。即使是结构良好的 XHTML 也会非常困难,但结构不佳的 HTML 则不能用于正则表达式。

我 100% 同意使用正则表达式来尝试 HTML 解析是一个非常糟糕的主意。下面的代码使用提供的函数来解析一些简单的 HTML 标记。当它找到嵌套的 HTML 标记 &lt;em&gt;Test&lt;em&gt; 时,它在第二次尝试时出错:

$t['label'] = 'Test';
$text = '<p>Test</p>';

$find = '/(?![^<]+>)(?<!\w)(' . preg_quote($t['label']) . ')\b/s';
$text = preg_replace_callback($find, 'replaceCallback', $text);

echo "Find:   $find\n";
echo 'Quote:  ' . preg_quote($t['label']) . "\n";
echo "Result: $text\n";

/* Returns:

Find:   /(?![^<]+>)(?<!\w)(Test)\b/s
Quote:  Test
Result: <p><a class="tag" rel="tag-definition" title="Click to know more about Test" href="?tag=Test">Test</a></p>

*/

$t['label'] = '<em>Test</em>';
$text = '<p>Test</p>';

$find = '/(?![^<]+>)(?<!\w)(' . preg_quote($t['label']) . ')\b/s';
$text = preg_replace_callback($find, 'replaceCallback', $text);

echo "Find:   $find\n";
echo 'Quote:  ' . preg_quote($t['label']) . "\n";
echo "Result: $text\n";

/* Returns:

Find:   /(?![^<]+>)(?<!\w)(Test)\b/s
Quote:  Test
Result: <p><a class="tag" rel="tag-definition" title="Click to know more about Test" href="?tag=Test">Test</a></p>
Warning: preg_replace_callback() [function.preg-replace-callback]: Unknown modifier '\' in /test.php  on line 25
Find:   /(?![^<]+>)(?<!\w)(\<em\>Test\</em\>)\b/s
Quote:  \<em\>Test\</em\>

Result: 

*/

function replaceCallback($match) {
    if (is_array($match)) {
        $htmlVersion = $match[1];
        $urlVersion = urlencode($htmlVersion);
        return '<a class="tag" rel="tag-definition" title="Click to know more about ' . $htmlVersion . '" href="?tag=' . $urlVersion . '">' . $htmlVersion . '</a>';
    }
    return $match;
}

【讨论】:

  • 好的,我想我明白了,html 对于正则表达式来说不够规则 :) 但是,你将如何用 html 内容中的超链接替换单词?
  • @pixeline: :-) 很抱歉,这只是一个到处出现的问题。正则表达式起初看起来是个好主意,但很少奏效。不管怎样,你应该试试 PHP 中的DOM functionsPHPro Parse HTML With PHP And DOM 教程也可能有所帮助。
  • @pixeline 像您这样的问题每天至少出现 3 次。搜索 替换 HTML 中的属性 或类似的关键字,或者只浏览几页前的问题。你想要的关键库是 DOM。
  • 它很完美,除了如果找到的关键字已经在A标签内,它会在A标签内创建一个A标签......我尝试的越多,我越觉得这个功能非常适合 html 片段。 DOM 在处理关键字方面非常糟糕。
猜你喜欢
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
  • 2017-06-30
  • 1970-01-01
  • 1970-01-01
  • 2019-11-09
  • 1970-01-01
相关资源
最近更新 更多