June 27th, 2010 By rex Categories: 教程

总结在 python 语言里使用正则表达式匹配中文的经验。关键词:中文,cjk,utf8,unicode,python。

Read more…

11 comments (439 Views)
June 21st, 2010 By rex Categories: 杂项

笔记三则,贴在这里。

Read more…

4 comments (450 Views)
June 20th, 2010 By rex Categories: 教程

浏览CU时发现Superor老师的《探索Perl的世界(更新到40集)-Perl 教学视频》(国人,中文),其中有5集是讲正则表达式的。观看之后觉得不错,贴在这里。 Read more…

0 comments (385 Views)
May 24th, 2010 By rex Categories: 教程, 问答

网友cfc4n问及关于(?!)的正则表达式问题。回答之后,顺便总结了一下Perl语言中如何匹配“不出现”某元素,贴在这里。 Read more…

1 comment (718 Views)
May 12th, 2010 By rex Categories: 应用

其实RegexBuddy挺好用的,我一直用它。它的用法、好处,可以写好多文字,本站也做过介绍;不过,也有理由不用它,同时这也是撰写本文的一个原因。我动了动脑筋,花了一点时间,已经做出雏形。现在将思路公布在这里,与各位交流一下。

Read more…

10 comments (1,070 Views)
May 10th, 2010 By rex Categories: 教程, 翻译

之前一篇文章翻译了Perl语言中的递归正则表达式. 其实不少语言中的正则都是支持递归的, 例如本文要介绍的PHP正则递归. 虽然, 工作中最常用的正则表达式都很”正则”, 只用最基本的语法就能解决85%以上的问题, 而且合理有效地使用普通正则来解决复杂问题也是一门技巧与学问; 但是高级一点的语法的确有它存的价值, 有时不用它还真办不了事儿; 况且学习正则的乐趣也在于尝试各种各样的可能性, 满足自己无穷无尽的好奇心.

本文内容, 整理自网文Finer points of PHP regular expressions. 其分析过程剥茧抽丝, 丝丝入扣, 值得一读. 该文系统地列出了PHP中正则表达式常见特性, 我只摘取其中递归部分翻译整理出来.

Read more…

4 comments (631 Views)
May 4th, 2010 By rex Categories: 杂项

原空间(homezz.com)到期, 顺便换为法国alwaysdata.com的了. 搬家很顺利, 使用scp将数据从原空间隔空传物过去; 配置好域名dns, 数据文件, 新空间就激活了. 很顺利.

另, 新站的访问速度如何? 可以接受吗?

目前在蕴酿一篇关于”如何DIY一款像RegexBuddy那样的正则表达式工具”的博客, 敬请期待.

6 comments (522 Views)
April 29th, 2010 By rex Categories: 杂项

本站在五一期间将更换空间。

7 comments (487 Views)
April 3rd, 2010 By rex Categories: 问答

问题

以下摘自某网友来信:

javascript正则中的否定前瞻

难点

  1. javascript不支持点号匹配换行符, 因此无法直接进行多行匹配;
  2. 处理前面没有http://, 当然要用否定前瞻( negative lookbehine)了:(?< !http:)\/\/. 可惜javascript不支持.
    javascript正则中的否定前瞻

Read more...

13 comments (1,187 Views)
March 27th, 2010 By rex Categories: 教程

IBM文库发布一篇新文章:

正则表达式新手和老手都可以一读。副标题“在大海里捞针”很有意思。

0 comments (681 Views)
March 20th, 2010 By rex Categories: 问答

chinaunix论坛上有这样一问:
搜索重复单词(“this this”)问题,问为什么第4行要加^:

1
2
3
4
5
6
7
    $/ = ".\n";
    while (<>) {
      next if !s/\b([a-z]+)((?:\s< <[^>]+>)+)(\1\b)/\e[7m$1\e[m$2\e[7m$3\e[m/ig;
      s/^(?:[^\e]*\n)+//mg;   # Remove any unmarked lines.   # 为何需要加^
      s/^/$ARGV: /mg;         # Ensure lines begin with filename.
      print;
    }

要解答这个问题,不能只print "hello world";着眼于这一行。程序不长,从头到尾详细读一下,这个问题就兵不血刃地解决了。 Read more…

0 comments (708 Views)
March 15th, 2010 By rex Categories: 应用

这两天写了一段perl程序,输入url地址,下载其中的文件,计算MD5值,查该文件是否是病毒;如果无记录,则调用另外一个perl脚本将其上传到某一网站作详细测试。我想说的是,这些功能可能使用bash来编程,会更直接;用perl来做bash的事情总有些越俎代庖。不过,目前我对perl极感兴趣;有机会就用它;另外,将不成熟的代码贴出来,留给未来的自己一个鄙视现在的自己的机会也好:)

一个小小的发现是,qx可以将所包含的语句当作bash命令来执行,并把结果返回。另外书中交待,eval也是极有用的,不过这次没用上,下次找机会牛刀小试一把。

之所以没有使用curl, md5等等模块,而是使用shell命令,是因为我所用的虚拟机里没有安装,但是它们是bash下标准的可执行文件。这样写来,效率会有点折扣,但是绿色便携。

无废话,贴代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/bin/perl -w

#this script offers a better download service
#integreting virustotal infor, send-sample.pl
#by rex.zhang
#on 03-11-2010 in Shanghai
#updated @003122010;

my ($url)=$ARGV[0];

#it is assumed that the filename is the last part of the url,
#just after the last / and before the $
main($url);

sub main
{
    my ($url)=@_;

    #print help message and quit if no url input;
    help() if (not $url);
   
    my ($md5,$size,$name);
    $url =~ /\/([^\/]+)$/;

    #get the filename from the url;
    $name=$1;

    #get filesize from the url; if no size got, quit.
    $size=get_filesize($url);
    exit if $size;

    #try 5 times at most to get the file.
    my ($try)=5;
    my $ok;
    while($try--)
    {
      $ok=download_file($url);
      last if $ok;
    }
    if (not $ok)
    {
        print "can not download the file, quit!\n";
        exit();
    }

    #get the md5 locally
    $md5=get_md5($name);

    #and the url link from $virustotal;
    my ($link)=get_vt_link($md5);
    if ($link)
    {
        #and even the virus infor;
        my ($info)=get_vt_info($link);
        if (not $info)
        {
            v_test($name,$md5);
            print "\nSample has been sent to vtest. \nthanks for using.\n\n";
        }
    }
}

#return the md5 value of the file.
#the filename is in the current directory
sub get_md5
{
    my ($filename)=@_;
    my $md5=`md5sum $filename`;
    $md5 =~ /^(\w{32})/;
    print "\nthe md5 of the $filename is:\t $1.\n";
    return $1;
}

#get the virustotal link with the given md5 value;
sub get_vt_link
{
    my($md5)=@_;
    my ($link)=`curl -s -e "https://www.virustotal.com" -d "x=80&y=23&hash=$md5" "http://www.virustotal.com/vt/en/consultamd5" | grep href`;
    my ($bool)= $link =~ /href="([^"]+)"/i;
        if ($bool)
        {
            return "http://www.virustotal.com".$1;
        }
        else
        {
            return 0;
        }
}

#get the virus infor according to a virus total infor link
sub get_vt_info
{
    my($url)=@_;
    my $line;
    my $sophos =0;     #if sophos has no detection, do the vtest.
        foreach (qx{curl -s $url})
        {
            $line.=$_;
        }
    my (@result) = $line=~ m!<tr[^>]*>\s*<td>(?:Sophos|Symantec|TrendMicro|McAfee)</td>.*?</tr>!sig;
    if (not @result)
    {
        print "\nNo record in VirusTotal. Sending v-test...\n";
        return $sophos;
    }

    print "\nvirustotal record found as following:\n";
    foreach (@result)
    {
        my $tmp=$_;
        $tmp =~ s/(<[^>]+>\s*)+/\t/sig;
        print $tmp."\n";
        if ($tmp =~ m/(?:Sophos[.\s0-9]+)(?!-)(\S+)\s*$/i)
        {
            $sophos=$1;
        }
    }
    print "\nSophos has detection as $sophos, no v-test needed.\n" if $sophos;
    print "you can read the virus details here:\n";
    print "\t$url\n\n";

    exit() if $sophos;
}

#get the filesize by using the curl -I option.
#print the filesize if it is greater than a given value, 2MB by default.
sub get_filesize{

    my ($url)=@_;
    my ($size,$unit);
    foreach (qx{curl -s -I $url})
    {
        if (/Content-Length:\s(\d+)/)
        {
            $size=$1;
        }
        if (/Accept-Ranges:\s(\w+)/)
        {
            $unit=$1;
        }
    }
    if (not $size)
    {
        print "can not get the length of the file, exit!\n";
        exit;
    }
    $size=int($size / 1024);

    my $flag=0;     #if flag=1 it is too large ;
    if ($size>1024 * 2)
    {
        $flag=1;
        print "the file is ${size}KB and greater than 2MB!\n";
        print "it is too large to be a virus. exit.\n";
    }
    else
    {
        print "\nThe file size is $size kb, downloading...\n\n";
    }
    $flag;
}

#simply download the file
sub download_file
{
    my ($url)=@_;
    $url =~ /([^\/]+)$/;
    my $filename=$1;
    `curl -O $url`;
    if (not -e $filename)
    {
        print "no filename, retrying...\n";
        return 0;
    }
    print "\nfile is downloaded and saved as $filename.\n";
    1;
}

#print the help message and exit if no url input
sub help
{
    print "Usage: ./dl http://.../file.exe\n";
    print "\tthe last part of the url is regarded as filename.\n";
    exit();
}

#send the v-test email, with md5 value in the subject.
sub v_test
{
    my ($file,$md5)=@_;
    `zip $file.zip $file`;
    `send-sample.pl -a $file.zip -s "$file.zip URL MD5 $md5"`;
}
0 comments (476 Views)
March 9th, 2010 By rex Categories: 应用

rex按:

写完上一篇文章之后,一直在考虑如何真正实现从普通文本中归纳正则表达式的实现。走了许多弯路,也学了不少知识。例如,perl黑豹书上复杂的数据结构、匿名散列和数组、refenrence;紫龙书上的状态机的构造,数据结构上图论的知识,都是很有用的。另外还新学了graphviz的用法。以前觉得很神秘,不过一用才发现很直观。本文的插图是使用online版本的graphviz画的。

除了本文的这种实现方法(基于图),我还使用另一种方式实现了,很简单:基于关键词。具体作法是,逐一读取每一行文本,使用\s+等将其split开,形成array;然后再对所有的array进行求交集的操作(使用hash),得到每一行都有的关键词;然后按从左到右的顺序建立这覆的正则式^(.*?)keyword1(.*?)keyword2….keywordN(.*?)$,再分别匹配每一行文本,得到hash的hash表,或者array的array,转置,并列输出,得到^(option1|option2…)keyword1(option..)…$这样的正则式。最后作为验证,再将所最终生成的正则与每一行匹配测试一下。

这样以词为单位做完之后,再逐个字母地分隔开来,递归地处理(option1|option2…)的部分。先是单词级,再是字母级,有利于先在最大程度上找出重复的内容;而且粗化和细化的处理过程,思路是一致的,粒度不同罢了。

新手请自重,高手请赐教,我的思路未必是正确或最优的。

Read more…

3 comments (883 Views)
February 10th, 2010 By rex Categories: 应用

近来工作中需要将某种明文字串转为简单的正则式。手动做当然可以,但是大量重复性的劳动,自然是交给机器处理为好。昨晚写了一款这样的脚本,放在这里。因为是处理我自己的工作的脚本,贴在这里仅作记录和存档之用,可能对别人没什么实际作用。当然,从现有的明文字串到正则式的转换,应该是个不错的题目,有兴趣朋友的可以深究。

值得一提的是,代码中用了$&, (?{}) 这样的perl only的东东,明晰了思路,简化了代码。如果不使用这种特性的话,代码要长5倍。另外,据说从效率上来说,use English之后,使用$MATCH比直接使用$&快5倍。但是对于即输入即执行的命令行程序来说,$&已经足够好。

Read more…

2 comments (727 Views)
February 6th, 2010 By rex Categories: 应用

假设样本文件a.txt内容如下:

1
2
3
4
5
6
hello world!
hello world!
I love regex.
hello world!
I love regex.
hello world!

简单观察可知,hello world!共重复4行;I love regex.重复2行。如何使用正则表达式来写一个程序,统计这些数据呢?因为现实中需要统计的文件,绝非是只凭肉眼就能观察出来。我想到了两种方法,第一种方法,是依赖于正则表达式(否则这篇文章也不会贴在这里);第二种,hash表做主角,正则表达式作绿叶。 Read more…

7 comments (1,227 Views)
Page 1 of 512345