【正则表达式】使用正则来取html中的正文的bug【原创】

今天碰到了一个问题,在写PHP,使用正则表达式来获取html中的body内容的时候,遇到了一个bug,不多说,先上代码,先上要取的html文件:
8/index.html:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>你好你好</title>
  6. <link rel="stylesheet" href="css/normalize.css">
  7. <link rel="stylesheet" href="css/style.css" media="screen" type="text/css" />
  8. </head>
  9. <body>
  10. <div style="text-align:center;clear:both;">
  11. <script src="/follow.js" type="text/javascript"></script>
  12. </div>
  13. <div class='heart3d'>
  14. <div class='rib1'></div>
  15. <div class='rib2'></div>
  16. <div class='rib3'></div>
  17. <div class='rib4'></div>
  18. </div>
  19. </body>
  20. </html>
没什么特别的html文件。

接着是php文件:
  1. <?php
  2. /**
  3. * 在html文件中找出正文
  4. * Created by PhpStorm.
  5. * User: Administrator
  6. * Date: 2016/11/15
  7. * Time: 21:43
  8. */
  9. $filename = '8/index.html';
  10. $res = get_body_from_html($filename);
  11. var_dump($res);
  12. /**
  13. * 在html文件中找出正文
  14. * @param $filename string 路径url
  15. * @return array|bool
  16. */
  17. function get_body_from_html($filename)
  18. {
  19. if (!file_exists($filename)) {
  20. return false;
  21. }
  22. $file = file_get_contents($filename);
  23. $res = array();
  24. preg_match('/<body>(.*)<\/body>/', $file, $res);
  25. return $res;
  26. }
结果一运行发现是空的:
  1. array(0) { }
为了测试,改了一下方法:
  1. function get_body_from_html($filename)
  2. {
  3. if (!file_exists($filename)) {
  4. return false;
  5. }
  6. // $file = file_get_contents($filename);
  7. $file = '<html><head><title>你好</title>></head><body><div>我不好我不好</div></body></html>';
  8. $res = array();
  9. preg_match('/<body>(.*)<\/body>/', $file, $res);
  10. return $res;
  11. }
运行发现没问题:
  1. array(2) {
  2. [0]=>
  3. string(42) "<body><div>我不好我不好</div></body>"
  4. [1]=>
  5. string(29) "<div>我不好我不好</div>"
  6. }


仔细检查代码,发现没啥问题,遂只好去segmentfault提问,很快就有了答案:
是因为正则的问题,.只能匹配除了换行符的所有字符,所以匹配不到html中的,一般要匹配所有字符的话,两种方法,一种是:([\s\S]*?),\s匹配所有的空白,包括空格、换行、tab缩进等所有的空白,而\S正好相反,这样\s\S就匹配所有的字符。[]表示在它里面包含的单个字符不限顺序的出现。类似的还有[\w\W]等,另外一种是给正则表达式添加模式修饰符/s。

所以修改后的代码为:
  1. <?php
  2. /**
  3. * 在html文件中找出正文
  4. * Created by PhpStorm.
  5. * User: Administrator
  6. * Date: 2016/11/15
  7. * Time: 21:43
  8. */
  9. $filename = '8/index.html';
  10. $res = get_body_from_html($filename);
  11. var_dump($res);
  12. /**
  13. * 在html文件中找出正文
  14. * @param $filename string 路径url
  15. * @return array|bool
  16. */
  17. function get_body_from_html($filename)
  18. {
  19. if (!file_exists($filename)) {
  20. return false;
  21. }
  22. $file = file_get_contents($filename);
  23. $res = array();
  24. preg_match('/<body>([\s\S]*?)<\/body>/', $file, $res);
  25. return $res[0];
  26. }
或者是:
  1. <?php
  2. /**
  3. * 在html文件中找出正文
  4. * Created by PhpStorm.
  5. * User: Administrator
  6. * Date: 2016/11/15
  7. * Time: 21:43
  8. */
  9. $filename = '8/index.html';
  10. $res = get_body_from_html($filename);
  11. var_dump($res);
  12. /**
  13. * 在html文件中找出正文
  14. * @param $filename string 路径url
  15. * @return array|bool
  16. */
  17. function get_body_from_html($filename)
  18. {
  19. if (!file_exists($filename)) {
  20. return false;
  21. }
  22. $file = file_get_contents($filename);
  23. $res = array();
  24. preg_match('/<body>(.*)<\/body>/s', $file, $res); //这一种方法也可以
  25. return $res[0];
  26. }


运行之后就没问题了:
  1. string(280) "<body>
  2. <div style="text-align:center;clear:both;">
  3. <script src="/follow.js" type="text/javascript"></script>
  4. </div>
  5. <div class='heart3d'>
  6. <div class='rib1'></div>
  7. <div class='rib2'></div>
  8. <div class='rib3'></div>
  9. <div class='rib4'></div>
  10. </div>
  11. </body>"

posted @ 2016-11-20 13:04  Newman·Li  阅读(405)  评论(0编辑  收藏  举报