LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 4812|回复: 12

如何从HTML文件中提取charset

[复制链接]
发表于 2003-7-21 19:51:56 | 显示全部楼层 |阅读模式
就是 <META http-equiv=Content-Type content="text/html; charset=gb2312"> 里的gb2312

我知道用perl的HTML parser模块会比较容易
but... 我不会perl还...

刚才瞎写了一个极其dirty的script,能够正常工作(至少中文HOWTO里的文档都可以正常输出),但效率比较低。
另外因为绝大部分非英语文档都很规范,所以我只取了前十五行来判断...


  1. #!/bin/sh

  2. DEFAULT_CHARSET=iso-8859-1

  3. CHARSET=$(head -15 $1 | tr ">" "\n" \
  4.         | grep -i 'meta[[:space:]].*charset *=' | tr ";" "\n" \
  5.         | grep -i charset | tr """ "\n" | tr -s "[[:space:]]" "\n" \
  6.         | tr "=" "\n" | tail -1)

  7. if [ -z $CHARSET ] ; then
  8.         echo $DEFAULT_CHARSET
  9. else
  10.         echo $CHARSET
  11. fi
复制代码


哪位能写个漂亮点的?现在这个实在是拿不出手呀!
thanks in advance....
发表于 2003-7-21 20:40:43 | 显示全部楼层
您这方法真有意思哦:
CHARSET=$(head -15 $1
取前15行
| tr ">" "\n" \
把">"替换成"\n"
| grep -i 'meta[[:space:]].*charset *='
寻找以meta开头,一个空格后接任意字符串,再接charset字串,然后在任意空格后接"="符号的行A。
| tr ";" "\n" \
把";"替换成"\n"
| grep -i charset
找含有charset字串的那行B
| tr "\"" "\n"
把"\""替换成"\n"
| tr -s "[[:space:]]" "\n" \
把空格替换成"\n"
| tr "=" "\n"
把"="替换成"\n"
| tail -1)
取倒数第二行

完成。

不错,不错。
 楼主| 发表于 2003-7-22 00:15:26 | 显示全部楼层
;)
想着想着就写成这个样子了...
用了5次"tr"
这还是精炼过的,刚写出来的时候用了7个"tr"呢...
发表于 2003-7-22 09:53:17 | 显示全部楼层
sed -ne 's/\(.*\)charset=\(.*\)"\(.*\)/\2/p' HTMLFILE
 楼主| 发表于 2003-7-22 15:53:35 | 显示全部楼层
兄台这个简单,好,but对文件要求太严...
title或正文里要是有"charset=xxx",等号两边有空格,等情况都会出错
发表于 2003-7-22 17:18:36 | 显示全部楼层
$ sed -n '1,15 s/\(^<[meta|META].*charset.*=\)\(.*\)\">$/\2/p' showthread.html | sed -e 's/\ //g'
 楼主| 发表于 2003-7-22 21:17:56 | 显示全部楼层
penny兄的方法也不错呀...
but... 如果文件是在mac/windows下写的就完蛋了... ;)
DOS格式文件行尾是“\r”, MAC文档则根本不用"\n"直接用"\r"来换行(tr/sed好象会把整个MAC文档当做一行来处理)

另外,几位大兄都只考虑了从一行代码中提取gb2312的问题
这也是我一开始要用 tr 原因
因为html文件不要求<>在一行内完成
比如
  1. <META http-equiv=Content-Type
  2. content="text/html;
  3. charset=gb2312">
复制代码

HOWTO文档中这样的文件比较多,不过中文的文档都很正规 ~_~
这就需要先按html语法重新组合语句,再sed...
而且对于sed -e 's/\ //g'这种简单字符替换,改用tr -d " "会比较清晰

现在偶的程序是这个样子
  1. #!/bin/sh
  2.                                                                                 
  3. HTML_CHARSET=$(head -15 $1 | tr -d "[\r\n]" | tr ">" "\n" | tr "[A-Z]" "[a-z]" \
  4. | sed -ne 's/\(.*meta.*content.*charset[[:space:]]*=[[:space:]]*\)\(.*\)\(".*\)/\2/p')

  5. if [ -z $HTML_CHARSET ] ; then
  6.     HTML_CHARSET=iso-8859-1
  7. fi

  8. echo "$HTML_CHARSET"
复制代码


偶电脑里所有的非英文HTML文档都可正确识别了
还是在解决实际问题时学东西比较快
谢谢各位
发表于 2003-7-23 11:21:08 | 显示全部楼层
tr ">" "\n" 这一部份应该不需要。
 楼主| 发表于 2003-7-23 14:34:25 | 显示全部楼层
试了一下,去掉tr ">" "\n"后,就不行了... 比如下面这个文件头
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  2. <html>
  3. <head><meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">
  4. <meta NAME="GENERATOR" CONTENT="ZH-SGML-Tools 1.0.9">
  5. <title>Linux HOWTO 中文索引</title>
  6. <link HREF="/cgi-bin/dwww?type=file&amp;location=/usr/share/doc/HOWTO/zh-s-html/HOWTO-INDEX-1.html" REL=next>
  7. </head>
  8. <body>
  9. <a HREF="/cgi-bin/dwww?type=file&amp;location=/usr/share/doc/HOWTO/zh-s-html/HOWTO-INDEX-1.html">Next</a>
  10. Previous
  11. Contents
  12. <hr>
  13. <h1>Linux HOWTO 中文索引</h1>
复制代码

由于我在前面把这十来行代码变换了一行
这一行中就会有多个双引号
现有程序会取最后一个双引号来分隔
结果就变成了gb2312">.....O/zh-s-html/HOWTO-INDEX-1.html
发表于 2003-7-23 16:23:58 | 显示全部楼层
将 \(.*\)\(".*\) 改为 \([^"]*\)\(.*\) 就应该可以?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表