LinuxSir.Org  
| 网站首页 | 注册账号 | 论坛帮助 |

欢迎来到LinuxSir.Org!
您还未登录,请登录后查看论坛,或者点击论坛上方的注册链接注册新账号。


发表新主题 回复
精华主题  
主题工具
旧 03-07-21, 19:51 第 1 帖
carlos
 
 
 
★☆临时★退役☆版主★☆  
  注册日期: Sep 2002
  我的住址: NZ
  帖子: 7,719
  精华: 24
 

标题: 请教如何从HTML文件中提取charset


就是 <META http-equiv=Content-Type content="text/html; charset=gb2312"> 里的gb2312

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

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

代码:
#!/bin/sh DEFAULT_CHARSET=iso-8859-1 CHARSET=$(head -15 $1 | tr ">" "\n" \ | grep -i 'meta[[:space:]].*charset *=' | tr ";" "\n" \ | grep -i charset | tr "\"" "\n" | tr -s "[[:space:]]" "\n" \ | tr "=" "\n" | tail -1) if [ -z $CHARSET ] ; then echo $DEFAULT_CHARSET else echo $CHARSET fi
哪位能写个漂亮点的?现在这个实在是拿不出手呀!
thanks in advance....







__________________
Aoccdrnig to a rscheearch at an Elingsh uinervtisy,
it deosn't mttaer in waht oredr the ltteers in a wrod are,
the olny iprmoetnt tihng is taht frist and lsat ltteer is at the rghit pclae.

此帖于 03-07-21 20:02 被 carlos 编辑.
  carlos 当前离线   回复时引用此帖
旧 03-07-21, 20:40 第 2 帖
dreamrise 帅哥
 
dreamrise 的头像
 
 
注册会员  
  注册日期: Nov 2002
  帖子: 396
  精华: 8
 

您这方法真有意思哦:
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)
取倒数第二行

完成。

不错,不错。
  dreamrise 当前离线   回复时引用此帖
旧 03-07-22, 00:15 第 3 帖
carlos
 
 
 
★☆临时★退役☆版主★☆  
  注册日期: Sep 2002
  我的住址: NZ
  帖子: 7,719
  精华: 24
 


想着想着就写成这个样子了...
用了5次"tr"
这还是精炼过的,刚写出来的时候用了7个"tr"呢...
  carlos 当前离线   回复时引用此帖
旧 03-07-22, 09:53 第 4 帖
kwokts
 
 
 
注册会员  
  注册日期: Nov 2002
  我的住址: 香港
  帖子: 616
  精华: 0
 

sed -ne 's/\(.*\)charset=\(.*\)"\(.*\)/\2/p' HTMLFILE
  kwokts 当前离线   回复时引用此帖
旧 03-07-22, 15:53 第 5 帖
carlos
 
 
 
★☆临时★退役☆版主★☆  
  注册日期: Sep 2002
  我的住址: NZ
  帖子: 7,719
  精华: 24
 

兄台这个简单,好,but对文件要求太严...
title或正文里要是有"charset=xxx",等号两边有空格,等情况都会出错
  carlos 当前离线   回复时引用此帖
旧 03-07-22, 17:18 第 6 帖
lucida
 
 
 
注册会员  
  注册日期: Oct 2002
  我的住址: .:DRL:.
  帖子: 2,492
  精华: 9
 

$ sed -n '1,15 s/\(^<[meta|META].*charset.*=\)\(.*\)\">$/\2/p' showthread.html | sed -e 's/\ //g'







__________________
E6300@3.2G/P5B-D WiFi/2G RAM/1TB HDD/3540A/7900GT/E-MU 0404
Logitech S 510/MX Revolution/2407WFP/LaserJet 1020
go wild, go Gentoo

此帖于 03-07-22 17:50 被 lucida 编辑.
  lucida 当前离线   回复时引用此帖
旧 03-07-22, 21:17 第 7 帖
carlos
 
 
 
★☆临时★退役☆版主★☆  
  注册日期: Sep 2002
  我的住址: NZ
  帖子: 7,719
  精华: 24
 

penny兄的方法也不错呀...
but... 如果文件是在mac/windows下写的就完蛋了...
DOS格式文件行尾是“\r”, MAC文档则根本不用"\n"直接用"\r"来换行(tr/sed好象会把整个MAC文档当做一行来处理)

另外,几位大兄都只考虑了从一行代码中提取gb2312的问题
这也是我一开始要用 tr 原因
因为html文件不要求<>在一行内完成
比如
代码:
<META http-equiv=Content-Type content="text/html; charset=gb2312">
HOWTO文档中这样的文件比较多,不过中文的文档都很正规 ~_~
这就需要先按html语法重新组合语句,再sed...
而且对于sed -e 's/\ //g'这种简单字符替换,改用tr -d " "会比较清晰

现在偶的程序是这个样子
代码:
#!/bin/sh HTML_CHARSET=$(head -15 $1 | tr -d "[\r\n]" | tr ">" "\n" | tr "[A-Z]" "[a-z]" \ | sed -ne 's/\(.*meta.*content.*charset[[:space:]]*=[[:space:]]*\)\(.*\)\(".*\)/\2/p') if [ -z $HTML_CHARSET ] ; then HTML_CHARSET=iso-8859-1 fi echo "$HTML_CHARSET"
偶电脑里所有的非英文HTML文档都可正确识别了
还是在解决实际问题时学东西比较快
谢谢各位

此帖于 03-07-22 21:58 被 carlos 编辑.
  carlos 当前离线   回复时引用此帖
旧 03-07-23, 11:21 第 8 帖
kwokts
 
 
 
注册会员  
  注册日期: Nov 2002
  我的住址: 香港
  帖子: 616
  精华: 0
 

tr ">" "\n" 这一部份应该不需要。
  kwokts 当前离线   回复时引用此帖
旧 03-07-23, 14:34 第 9 帖
carlos
 
 
 
★☆临时★退役☆版主★☆  
  注册日期: Sep 2002
  我的住址: NZ
  帖子: 7,719
  精华: 24
 

试了一下,去掉tr ">" "\n"后,就不行了... 比如下面这个文件头
代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <html> <head><meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312"> <meta NAME="GENERATOR" CONTENT="ZH-SGML-Tools 1.0.9"> <title>Linux HOWTO 中文索引</title> <link HREF="/cgi-bin/dwww?type=file&amp;location=/usr/share/doc/HOWTO/zh-s-html/HOWTO-INDEX-1.html" REL=next> </head> <body> <a HREF="/cgi-bin/dwww?type=file&amp;location=/usr/share/doc/HOWTO/zh-s-html/HOWTO-INDEX-1.html">Next</a> Previous Contents <hr> <h1>Linux HOWTO 中文索引</h1>
由于我在前面把这十来行代码变换了一行
这一行中就会有多个双引号
现有程序会取最后一个双引号来分隔
结果就变成了gb2312">.....O/zh-s-html/HOWTO-INDEX-1.html
  carlos 当前离线   回复时引用此帖
旧 03-07-23, 16:23 第 10 帖
kwokts
 
 
 
注册会员  
  注册日期: Nov 2002
  我的住址: 香港
  帖子: 616
  精华: 0
 

将 \(.*\)\(".*\) 改为 \([^"]*\)\(.*\) 就应该可以?
  kwokts 当前离线   回复时引用此帖
旧 03-07-23, 19:44 第 11 帖
carlos
 
 
 
★☆临时★退役☆版主★☆  
  注册日期: Sep 2002
  我的住址: NZ
  帖子: 7,719
  精华: 24
 

no. 不起作用
要把 \(.*\)\(".*\) 改为 \([[:alnum:]-]*\)\(".*\) 才行
我还是决定使用 tr ">" "\n" ,虽然这样会使效率下降一点
但成功率和保险系数会高一些
(用time测了一下,在我的PIII900上分析700个html文件,后者比前者比多花3秒钟 32s - 29s)

thanks anyway...
  carlos 当前离线   回复时引用此帖
旧 03-07-24, 14:24 第 12 帖
kwokts
 
 
 
注册会员  
  注册日期: Nov 2002
  我的住址: 香港
  帖子: 616
  精华: 0
 

如果是在 Pentium 或 486 下,分别是很明显的。
效率是要考虑的因素之一。
  kwokts 当前离线   回复时引用此帖
旧 03-07-24, 19:19 第 13 帖
carlos
 
 
 
★☆临时★退役☆版主★☆  
  注册日期: Sep 2002
  我的住址: NZ
  帖子: 7,719
  精华: 24
 

这个程序是用在本地web服务器的cgi中
一次只会处理一个html文件
就算是pentium 166,延时也很难察觉..

此帖于 03-07-24 19:32 被 carlos 编辑.
  carlos 当前离线   回复时引用此帖
发表新主题 回复


主题工具

发帖规则
您 [不可以] 发表新主题
您 [不可以] 回复主题
您 [不可以] 上传附件
您 [不可以] 编辑您的帖子

已 [启用] BB 代码
已 [启用] 表情符号
已 [启用] IMG 代码
已 [禁用] HTML 代码
[论坛跳转…]


所有时间均为[北京时间]。现在的时间是 13:18


Powered by vBulletin 版本 3.6.8
版权所有 ©2000 - 2010, Jelsoft Enterprises Ltd.
官方中文技术支持: vBulletin 中文
版权所有 ©2002 - 2009, LinuxSir.Org