繁体   English   中英

用preg_replace替换字符集

[英]Replacing charset with preg_replace

我将不同的网站内容存储在名为$ content的变量中。 现在,我想做的就是在内容中搜索像这样的META标签:

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

然后将utf-8替换为IS0-8859-1。 我该如何使用preg_replace?

请注意,每次出现都与该元标记不同。 根据您获取哪个网站,它可能会有所不同。

您无需使用preg_replace即可。 只需使用str_replace

$content = str_replace('; charset=utf-8', '; charset=ISO-8859-1', $content);

那么这样的事情呢:

$input = 'sometext<meta http-equiv="Content-type" content="text/html; charset=utf-8" />someothertext';

$output = preg_replace('#<meta http-equiv="Content-type" content="text/html; charset=(utf-8)" />#', 
    '<meta http-equiv="Content-type" content="text/html; charset=IS0-8859-1" />', 
    $input);

var_dump($output);

只需将第二个字符串替换为第一个字符串,即可:

string 'sometext<meta http-equiv="Content-type" content="text/html; charset=IS0-8859-1" />someothertext' (length=95)

当然,这是在考虑输入元始终是相同的,总是以相同的方式编写,具有相同顺序的属性。

正则表达式可能会更宽容一些:

$output = preg_replace('#<meta\s+http-equiv="Content-type"\s+content="text/html;\s+charset=(utf-8)"\s+/>#', 
    '<meta http-equiv="Content-type" content="text/html; charset=IS0-8859-1" />', 
    $input);

当然,那仍然不是真正的宽恕^^


但是, 如果您知道用作输入的元数据总是一样的,则不需要正则表达式 我想str_replace会做的很好。

像这样的东西:

$output = str_replace('<meta http-equiv="Content-type" content="text/html; charset=utf-8" />', 
    '<meta http-equiv="Content-type" content="text/html; charset=IS0-8859-1" />', 
    $input);
var_dump($output);

这将为您提供相同的输出:

string 'sometext<meta http-equiv="Content-type" content="text/html; charset=IS0-8859-1" />someothertext' (length=95)



在评论和OP版本之后进行编辑
(是的,我已经看到基于str_replace的另一个答案了……不过,也许这会很有用)

如果您确实想操纵不受控制的非“固定” HTML,则最好完全不使用正则表达式,但是为此专门使用了一些工具。

例如,捆绑的类DOMDocument和它的DOMDocument::loadHTML可能会有所帮助; 也许再加上一些XPath查询 - 即使它有点感觉像重炮^^

欲了解更多信息,你可以看看这个答案我前几天给了另一个问题?

而且,在您的情况下,可能会这样:

$input = <<<HTML
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <title>Test</title>
</head>
<body>
    <p>Hello, world!</p>
</body>
</html>
HTML;

$dom = new DOMDocument();
$dom->loadHTML($input);

$xpath = new DOMXpath($dom);
$metas = $xpath->query('//meta[@http-equiv="Content-type"]');

if ($metas->length > 0) {
    $meta = $metas->item(0);
    $attribute = $meta->getAttribute('content');
    if (strpos($attribute, 'text/html') === 0) {
        $meta->setAttribute('content', 'text/html; charset=ISO-8859-1');
    }
}

echo $dom->saveHTML();

最有趣的部分是:

  • 您正在使用带有标准DOM方法的DOM解析器
  • 您可以执行XPath查询来精确定位所需的元素


生成的HTML将如下所示:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=ISO-8859-1">
<title>Test</title>
</head>
<body>
    <p>Hello, world!</p>
</body>
</html>

也许有点重,并且需要更多代码...但是,这样,它应该总是可以工作(好吧,只要输入所用的HTML不太混乱,我想)。

它将适用于文档中的其他任何内容;-)


在您的情况下可能有点过多,但是,幸运的是,您会记住这一天,您必须解析一些HTML,并且最终不会与任何形式的突变正则表达式进行斗争^^


哦,而且,当然:更改meta内容类型不会更改内容的真实编码:如有必要,您仍然必须自己做(例如,请参阅iconvutf8_decode

您可能还需要更改HTTP Content-type标头(如果设置了HTTP标头,则不确定浏览器如何处理元数据)

您可以只匹配'charset = *“',然后将*替换为” ISO-8859-1“。

像这样:

$content = preg_replace('/(charset=)(.+)\"/', "$1"."ISO-8859-1", $content);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM