【正则表达式】使用正则来取html中的正文的bug【原创】
今天碰到了一个问题,在写PHP,使用正则表达式来获取html中的body内容的时候,遇到了一个bug,不多说,先上代码,先上要取的html文件:
8/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>你好你好</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css" media="screen" type="text/css" />
</head>
<body>
<div style="text-align:center;clear:both;">
<script src="/follow.js" type="text/javascript"></script>
</div>
<div class='heart3d'>
<div class='rib1'></div>
<div class='rib2'></div>
<div class='rib3'></div>
<div class='rib4'></div>
</div>
</body>
</html>
没什么特别的html文件。
接着是php文件:
<?php
/**
* 在html文件中找出正文
* Created by PhpStorm.
* User: Administrator
* Date: 2016/11/15
* Time: 21:43
*/
$filename = '8/index.html';
$res = get_body_from_html($filename);
var_dump($res);
/**
* 在html文件中找出正文
* @param $filename string 路径url
* @return array|bool
*/
function get_body_from_html($filename)
{
if (!file_exists($filename)) {
return false;
}
$file = file_get_contents($filename);
$res = array();
preg_match('/<body>(.*)<\/body>/', $file, $res);
return $res;
}
结果一运行发现是空的:
array(0) { }
为了测试,改了一下方法:
function get_body_from_html($filename)
{
if (!file_exists($filename)) {
return false;
}
// $file = file_get_contents($filename);
$file = '<html><head><title>你好</title>></head><body><div>我不好我不好</div></body></html>';
$res = array();
preg_match('/<body>(.*)<\/body>/', $file, $res);
return $res;
}
运行发现没问题:
array(2) {
[0]=>
string(42) "<body><div>我不好我不好</div></body>"
[1]=>
string(29) "<div>我不好我不好</div>"
}
仔细检查代码,发现没啥问题,遂只好去
segmentfault提问,很快就有了答案:
是因为正则的问题,
.只能匹配除了换行符的所有字符,所以匹配不到html中的,一般要匹配所有字符的话,两种方法,一种是:([\s\S]*?),\s匹配所有的空白,包括空格、换行、tab缩进等所有的空白,而\S正好相反,这样\s\S就匹配所有的字符。[]表示在它里面包含的单个字符不限顺序的出现。类似的还有[\w\W]等,另外一种是给正则表达式添加模式修饰符/s。
所以修改后的代码为:
<?php
/**
* 在html文件中找出正文
* Created by PhpStorm.
* User: Administrator
* Date: 2016/11/15
* Time: 21:43
*/
$filename = '8/index.html';
$res = get_body_from_html($filename);
var_dump($res);
/**
* 在html文件中找出正文
* @param $filename string 路径url
* @return array|bool
*/
function get_body_from_html($filename)
{
if (!file_exists($filename)) {
return false;
}
$file = file_get_contents($filename);
$res = array();
preg_match('/<body>([\s\S]*?)<\/body>/', $file, $res);
return $res[0];
}
或者是:
<?php
/**
* 在html文件中找出正文
* Created by PhpStorm.
* User: Administrator
* Date: 2016/11/15
* Time: 21:43
*/
$filename = '8/index.html';
$res = get_body_from_html($filename);
var_dump($res);
/**
* 在html文件中找出正文
* @param $filename string 路径url
* @return array|bool
*/
function get_body_from_html($filename)
{
if (!file_exists($filename)) {
return false;
}
$file = file_get_contents($filename);
$res = array();
preg_match('/<body>(.*)<\/body>/s', $file, $res); //这一种方法也可以
return $res[0];
}
运行之后就没问题了:
string(280) "<body>
<div style="text-align:center;clear:both;">
<script src="/follow.js" type="text/javascript"></script>
</div>
<div class='heart3d'>
<div class='rib1'></div>
<div class='rib2'></div>
<div class='rib3'></div>
<div class='rib4'></div>
</div>
</body>"