标题: [原创代码] [Perl]在线查询英汉对译 V1.66 支持中文/剪切板取词 [打印本页]
作者: 523066680 时间: 2015-6-13 10:55 标题: [Perl]在线查询英汉对译 V1.66 支持中文/剪切板取词
本帖最后由 523066680 于 2015-6-14 21:34 编辑
测试环境:WIN XP or WIN7 32/64 , Perl v5.16 (ActiveState)
代码保存为UTF8编码格式,查询dict.cn网站的翻译结果
(一直想要一个终端版的翻译工具,挂着其他翻译工具或者开浏览器总感觉耗内存)
V1.3 更新内容
支持剪切板获取,同时可以在终端进行输入(在输入单个字符后自动切换到<STDIN>,节约循环开销)
按 / 或者 ESC 或者 输入exit 退出
V1.60 更新内容
添加了中文输入的判断处理(毕竟Term::ReadKey是逐字节读取,不过还好,Read两个字节后转<STDIN>小事化无)
如果Ctrl+C中文文本,需要确保系统默认输入法为中文,否则可能提取为乱码
V1.65 增加剪切板访问开关(按Tab键切换),修正部分文字、符号判断的BUG
- =info
- Code by : 523066680@163.com
- Date : 2015-06-14
- Version : 1.66
-
- 按 Tab 键切换剪切板访问开关
- 键入 quit/exit 或者 按 ESC 退出
- =cut
-
- use v5.16; # given
- use utf8;
- use Encode;
- use IO::Handle;
- use LWP::Simple;
- use Term::ReadKey;
- use Win32::Clipboard;
-
- use Time::HiRes 'sleep';
- ReadMode 4; #Turn off controls keys
-
- system("");
- STDOUT->autoflush(1);
- binmode(STDOUT, ":encoding(gbk)");
-
- our $clip = Win32::Clipboard->new();
- our $main = "http:\/\/dict.cn";
- our $Clip_Access = 1;
-
- my $text;
- my $word;
- my $key;
- my $i = 0;
- $clip->Empty();
-
- notice();
-
- MAIN: while (1)
- {
- clipboardEvent() if ( $Clip_Access == 1 );
- keyboardEvent();
-
- print $i == 0 ? "_\b" : " \b";
- $i = 1 - $i;
- sleep 0.2;
- }
-
- sub keyboardEvent
- {
- my $word;
-
- $word = ReadKey(-1);
- given ($word)
- {
- when ( /\r/ ) { break; } # ReadKey状态下按 Enter = \r
- when ( /\e/ ) { exit ; } # 按 ESC 退出
- when ( /\t/ ) { switch_CA(); }
- when ( /.{1}/ ) { readContinue($word); }
- }
- }
-
- sub switch_CA
- {
- our $Clip_Access;
- $Clip_Access = 1 - $Clip_Access;
- notice();
- }
-
- sub readContinue
- {
- my $word = shift;
- my $LANG;
-
- if ( ord($word) > 128 ) #非ANSII即GBK
- {
- $word .= ReadKey(-1); #读入后半字节
- if ( $word =~ /^[\xA1-\xA9]/ ) { break; } #GBK 符号区域
- $LANG = "CHN";
- }
- else
- {
- if ( $word =~ /[^a-zA-Z]/ ) { break; }
- $LANG = "ENG";
- }
-
- print " ", decode('gbk', $word); #首字符输出
- $word .= <STDIN>;
- chomp $word;
- $word = decode('gbk', $word);
-
- if ( $word =~ /^(quit|exit)$/i ) { exit; }
- trans($word, $LANG);
- }
-
- sub clipboardEvent
- {
- our $clip;
- my $text;
-
- $text = $clip->GetText();
- $text = decode('gbk', $text);
-
- if ( $text =~ /\p{IsWord}/ )
- {
- #if ($text =~/\W/) { return; }
- #最多匹配3个词
- unless ( $text =~ /^( ?\p{IsWord}+ ?){1,3}$/ )
- {
- return;
- }
-
- print " $text {Clipboard}\n";
- given ($text)
- {
- when (/\p{han}/) { trans($text, "CHN"); }
- when (/[\w ]+/) { trans($text, "ENG"); }
- }
- $clip->Empty();
- }
- }
-
- sub trans
- {
- our $main;
- my $word = shift;
- my $type = shift;
- my $all;
- my $chk = 0;
-
- $word = encode('utf8', $word);
- $all = get("$main/$word") or warn "$!";
-
- $chk =
- $type eq 'CHN' ?
- Chn2Eng(\$all) : Eng2Chn(\$all);
-
- if ($chk == 0)
- {
- print "找不到该单词的翻译信息。\n";
- }
-
- print "\n";
- notice();
- }
-
- sub notice {
- our $enable;
- state $tip =
- {
- 0 => "关",
- 1 => "开",
- };
- print "\b \b"x80;
- print "(剪切板访问:". $tip->{ $Clip_Access };
- print ") 请输入单词:";
- }
-
-
- sub Chn2Eng
- {
- my $ref = shift;
- my $start;
- my $chk = 0;
- for (split("\n", ${$ref}))
- {
- if ( /<div class="layout cn">/i ) { $start = 1; }
- if ( $start == 1 )
- {
- if ( /<li><a href.*>(.*)<\/a><\/li>/i )
- {
- print $1,"\n";
- $chk++;
- }
- elsif ( /<\/div>/i )
- {
- last;
- }
- }
- }
- return $chk;
- }
-
- sub Eng2Chn
- {
- my $ref = shift;
- my $chk = 0;
- for (split("\n", ${$ref}))
- {
- if (/<li><span>(.*)<\/span>
- <strong>(.*)<\/strong>
- /ix
- ) {
- print $1, $2,"\n";
- $chk++;
- }
- }
- return $chk;
- }
复制代码
作者: aa77dd@163.com 时间: 2015-6-13 12:19
关于占内存问题, 太同感了
这个能不能改成监视剪贴板, 这样就能用 Ctrl+C, 很方便, 同时可能需要设计一个便捷的开关可以用来关掉监视
作者: 523066680 时间: 2015-6-13 12:35
本帖最后由 523066680 于 2015-6-13 23:09 编辑
回复 2# aa77dd@163.com
剪切板的可以,晚上弄。这次的脚本打算慢慢改进更新
再来一张
作者: 523066680 时间: 2015-6-13 22:48
回复 2# aa77dd@163.com
已添加剪切板读取功能,只在剪切版内容为单词、短语的时候尝试翻译
同时支持终端输入
作者: aa77dd@163.com 时间: 2015-6-14 08:34
本帖最后由 aa77dd@163.com 于 2015-6-14 08:42 编辑
回复 4# 523066680
NICE!
我在找怎么能支持 长了空白尾巴的单词, 比如 "word ", "hello ", "perl "
我有个习惯: 在浏览器(也包括 windows 记事本)里一段英文句子里某个单词上双击, 但选词结果就经常包括了后面的空白字符, 比如有 空格, TAB 字符, 等
我想应该是修改这行的正则表达式:- if ( $text =~ /\p{IsWord}/ )
复制代码
作者: 523066680 时间: 2015-6-14 09:02
本帖最后由 523066680 于 2015-6-14 09:04 编辑
回复 5# aa77dd@163.com
if ( $text =~ /\p{IsWord}/ )
{
if ($text =~/\W/) { return; } #空格或者其他符号类字符的情况被排除掉是因为这句
\w 匹配任何“字”字符(字母数字加"_" )。
\W 匹配任何“非字”字符。
用#注释掉就可以了,也可以自己定制一下
作者: aa77dd@163.com 时间: 2015-6-14 09:43
回复 6# 523066680
ha ha 那就私人定制了
我改成了:- if ($text !~ /^\s*[a-z]+\s*$|^\s*[a-z]+\s*[a-z]+\s*$|^\s*[a-z]+\s*[a-z]+\s*[a-z]+\s*$/i) { return; }
复制代码
可以最多支持包含三个单词的短语, 单词前后有空白字符都不会被拒绝翻译了
作者: aa77dd@163.com 时间: 2015-6-14 10:18
做了个简单的测试对比
[Perl]在线查询dict.cn英汉对译 V1.6 VS Lingoes 2.9.2 Home - 绿色便捷版
对比内容: 内存占用
以下 7 次 输出按先后顺序分别是 刚启动程序, 对剪贴板取词翻译 1次, 2次, ...6次 的内存占用
单词依次为: clip, text, decode, class, strong, print- (tasklist | findstr "perl.exe") & (tasklist | findstr "Lingoes.exe")
- perl.exe 4216 Console 1 19,248 K
- Lingoes.exe 7660 Console 1 30,476 K
- (tasklist | findstr "perl.exe") & (tasklist | findstr "Lingoes.exe")
- perl.exe 4216 Console 1 28,948 K
- Lingoes.exe 7660 Console 1 50,268 K
- (tasklist | findstr "perl.exe") & (tasklist | findstr "Lingoes.exe")
- perl.exe 4216 Console 1 29,392 K
- Lingoes.exe 7660 Console 1 50,592 K
- (tasklist | findstr "perl.exe") & (tasklist | findstr "Lingoes.exe")
- perl.exe 4216 Console 1 29,392 K
- Lingoes.exe 7660 Console 1 50,920 K
- (tasklist | findstr "perl.exe") & (tasklist | findstr "Lingoes.exe")
- perl.exe 4216 Console 1 29,680 K
- Lingoes.exe 7660 Console 1 51,900 K
- (tasklist | findstr "perl.exe") & (tasklist | findstr "Lingoes.exe")
- perl.exe 4216 Console 1 29,668 K
- Lingoes.exe 7660 Console 1 52,056 K
- (tasklist | findstr "perl.exe") & (tasklist | findstr "Lingoes.exe")
- perl.exe 4216 Console 1 29,768 K
- Lingoes.exe 7660 Console 1 52,484 K
复制代码
作者: 523066680 时间: 2015-6-14 10:42
本帖最后由 523066680 于 2015-6-14 10:48 编辑
回复 8# aa77dd@163.com
看来这个lingoes工具还好啊,以前用金山词霸感觉占用好高。
后来bing好像也用的不太流畅感觉。至于浏览器就呵呵…… 分分钟上百MB
30MB左右也不小了,我这里任务管理器观察的是7MB-13MB
刚刚探索了一下匹配一到三个词汇的,
unless ($text =~ /^( ?\p{IsWord}+ ?){1,3}$/) { return; }
作者: 523066680 时间: 2015-6-14 10:57
本帖最后由 523066680 于 2015-6-14 12:56 编辑
回复 8# aa77dd@163.com
话说跟正宗的软件不能比,各种细节。
只是多一个选择。本来是打算做成终端调用,偶尔用一下的,比如
>trans.pl abc
音频地址也找到了 : )
作者: aa77dd@163.com 时间: 2015-6-14 12:58
回复 11# 523066680
音频和纯文本的翻译内容比起来, 相对就超大了, 文本内容出来时不用等音频到位吧, 不然可能会被音频下载速度拖得卡住吧
考虑了本地音频库, 显然音频库也会占用较庞大的磁盘空间, 而且从加载速度考虑可能需要数据索引, 更麻烦了
作者: aa77dd@163.com 时间: 2015-6-14 13:01
回复 10# 523066680
感觉翻译软件通常都会用 tooltip 的形式即时显示翻译结果, 不知 Perl 来实现这个会不会搞得太大, 太大就不好了.
作者: 523066680 时间: 2015-6-14 15:46
回复 12# aa77dd@163.com
下一步是找个离线字典并想办法读出来
作者: 523066680 时间: 2015-6-18 09:05
本帖最后由 523066680 于 2015-6-18 09:40 编辑
回复 12# aa77dd@163.com
兄弟有没有明文的离线字典?前几天下了有道的和金山的离线包,
靠,看不懂=_= 不知道他们的数据封装格式。有道的英汉字典有3个字典文件,一个idx索引文件
补充1:找到一个云词的离线字典资源挺充足,图片声音都可以分开下,db3文件,待会找个数据库软件打开试试
http://www.remword.cn/portal.php?mod=topic&topicid=7
作者: 523066680 时间: 2015-6-18 19:11
下了一个旧软件的离线字典,找到了idx文件和lib文件的对照规律
然后发现做了简单的“加密”,还好不是很复杂的,仅仅是对每个字节的值做了偏移
作者: aa77dd@163.com 时间: 2015-6-19 11:37
本帖最后由 aa77dd@163.com 于 2015-6-19 11:43 编辑
回复 14# 523066680
不知道这些地方能不能找到些资源
http://www.pdawiki.com/forum/thread-10267-1-1.html
http://www.lingoes.cn/zh/dictionary/dict_format.php
http://www.octopus-studio.com/download.cn.htm
http://www.pdawiki.com/forum/forum.php
作者: 523066680 时间: 2015-6-23 09:36
回复 16# aa77dd@163.com
虽然有其他明文资源,不过本着蛋疼的心态还是把有道的离线字典拆解完了
另外下载了dict.cn的桌面版,发现整体体验不错啊!占用内存仅19MB 但是刚打开的时候不知道是什么导致的莫名的卡。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |