我需要什么样的正则表达式?

时间:2009-10-06 08:50:18

标签: php regex

我需要一个正则表达式(用PHP工作)用英式英语单词替换HTML中的美式英语单词。因此,颜色将被颜色取代,以米为单位等等[我知道米也是英国英语单词,但对于副本我们将使用它将始终指的是距离单位而不是测量设备]。该模式需要在以下(略微设计的)示例中准确工作(尽管由于我无法控制实际输入,因此可能存在):

<span style="color:red">This is the color red</span>

[不应替换HTML标记中的颜色,但应在句子中替换它]

<p>Color: red</p>

[应该替换单词]

<p>Tony Brammeter lives 2000 meters from his sister</p>

[应替换单词的米而不是名称]

我知道有一些边缘情况,替换不会有用(例如,如果他的名字是Tony Meter),但这些很少见,我们可以在他们出现时处理它们。

5 个答案:

答案 0 :(得分:5)

不应使用正则表达式处理Html / xml,真的很难生成一个匹配anything的表达式。但是你可以使用内置的dom extension并递归处理你的字符串:

# Warning: untested code!
function process($node, $replaceRules) {
    foreach ($node->children as $childNode) {
        if ($childNode instanceof DOMTextNode) {
            $text = pre_replace(
                array_keys(replaceRules),
                array_values($replaceRules),
                $childNode->wholeText
            );
            $node->replaceChild($childNode, new DOMTextNode($text));
        } else {
            process($childNode, $replaceRules);
        }
    }
}
$replaceRules = array(
    '/\bcolor\b/i' => 'colour',
    '/\bmeter\b/i' => 'metre',
);
$doc = new DOMDocument();
$doc->loadHtml($htmlString);
process($doc, $replaceRules);
$htmlString = $doc->saveHTML();

答案 1 :(得分:4)

我认为你需要一本字典,甚至可能需要一些语法分析才能使其正常工作,因为你无法控制输入。纯正则表达式解决方案实际上无法正确处理此类数据。

所以我建议首先想出一个需要替换的单词列表,这些单词不仅仅是“color”和“meter”。 Wikipedia has some information on the topic

答案 2 :(得分:1)

您不需要正则表达式。正则表达式本质上是无状态的,你需要一些状态来衡量'在html标签'和'在数据中'之间的区别。

你希望将HTML解析器与str_replace这样的东西结合使用,甚至更好,使用正确的语法词典和Lucero建议的东西。

答案 3 :(得分:1)

第二个问题更容易 - 你想在单词周围有单词边界时进行替换:http://www.regular-expressions.info/wordboundaries.html - 这将确保你不用Brammeter替换仪表。

第一个问题要困难得多。您不想替换HTML实体中的单词 - &lt;&gt;之间没有任何内容字符。所以,你的比赛必须确保你上次看到&gt;或者没有,但从来没有&lt;。这要么很难,要求lookahead/lookbehind assertions的某种组合,或者只是普通表达式不可能。

实现状态机的脚本在这里可以更好地工作。

答案 4 :(得分:0)

您不需要显式使用正则表达式。您可以尝试str_replace函数,或者如果您需要它不区分大小写,请使用str_ireplace函数。

示例:

$str = "<p>Color: red</p>";
$new_str = str_ireplace ('%color%', 'colour', $str);

您可以传递一个包含您要搜索的所有单词的数组,而不是字符串。