370 likes | 790 Views
Perl 语言与自然语言处理. 荀恩东. Perl 是什么?. Perl 是解释性的脚本语言 Larry Wall 于1987年,为进行文本处理和系统管理编写。 综合了 c,sh, awk 和 sed 的优点。 开放源代码,免费下载安装程序。 Perl 不是 GUI 程序。 Perl 是用 C 程序编写。 Perl 的优点 出色卓越的处理文本能力。 是跨平台的编程语言, window,linux … 自主内存管理,没有内存泄漏问题。 强大便捷的模块化功能。 下载安装程序 ActivePerl for Windows http://www.perl.com.
E N D
Perl语言与自然语言处理 荀恩东
Perl是什么? • Perl是解释性的脚本语言 • Larry Wall于1987年,为进行文本处理和系统管理编写。 • 综合了c,sh, awk和sed的优点。 • 开放源代码,免费下载安装程序。 • Perl不是GUI程序。 • Perl是用C程序编写。 • Perl的优点 • 出色卓越的处理文本能力。 • 是跨平台的编程语言,window,linux… • 自主内存管理,没有内存泄漏问题。 • 强大便捷的模块化功能。 • 下载安装程序 • ActivePerl for Windows http://www.perl.com
内容介绍 • Perl语言 • Perl变量类型 • 模式匹配 • Perl控制结构 • Perl在自然语言处理中应用 • 查词典、词典合并、词频统计、汉语分词 • 词性标注、 简繁转换 • 网络机器人、调用Google API • Perl其他典型应用 • 建立CGI网络应用 • 与数据库的接口 • 在C语言中,使用Perl
Perl变量类型 • 简单变量可以是数值,字符串,不作严格的区分。名字前面加上一个“$” 。 例如: $Data= 123; $string=“123”; • 数组 名字前面加上一个“@”,表示数组变量。 @array=(1,2,3,4,5); @array=(“a”,”b”,”c”); @array=(1,”b”,”c”); • 哈希表(hash) --名字前面加上一个“@”,表示数组变量。 %hash=(“hello”=>“哈罗”,“nihao”=>“你好”,“data”=>1); %hash=(“hello”,“哈罗”,“nihao”,“你好”,“data”,1); • 文件句柄 open(FILEHANDLE,"test.htm"); close(FILEHANDLE); • 引用 使用“\”来生成引用。 $Pointer=\$string;$Pointer=\@array; $Pointer=\@hash; 常用于函数调用参数传递,构造复杂数据结构
简单变量类型(1) • 以$开始 • 整型 • 十进制 $x = 12345; • 8进制 $x = 020;(16) • 16进制 $x = 0x20; (32) • 浮点数 • 11.4 、 -0.3 、.3 、 3. 、 54.1e+02 、 5.41e03 • $value = 9.01e+21 + 0.01 - 9.01e+21; • 字符串
简单变量类型(2) • 字符串 $Str=“this is a string”; $Str=‘this is a string’; • 转义字符 • 双引号内可以包含转义字符和其他变量 $number=11; $text = "This text contains the number $number."; $text = “\tThis text contains the number\n”; • 单引号内就是字符本身,单引号支持多行赋值 print ‘\tThis text contains the number\n’;
针对简单变量的操作符(3) • 算术操作符 • +, -, *, **, %, - • 整数比较操作符 • <, =, >. !=. >=, <=,<=> • 字符串比较操作符 • lt, gt, le,ge, eq, ne,cmp • 字符串操作函数 • chop,chomp,substr,length .(连接符) • 逻辑操作符 • &&, ||, !, xor • 赋值操作符 • =, +=.-=,*=,/=,**=,%=, • 自增自减操作符 • ++,-- • 条件操作符 • 条件?值1:值2,当条件为真时取值1,为假时取值2 $Num=$One ne $Two?1:2;
数组(1) • 数组变量 • 表示以@开头 • 数组的的元素可以是数值、字符串或两者的混合 • 数组的赋值 • @array = (2, 3, 4); • @array = (‘str1’, “\tstr2”, “str3”); • $str4=“str4”; @ array = (‘str1’, “\tstr2”, $str4); • @array = (1..3,4,5); • @day_of_month = ("01".."31") • @array = (e..f); @array= (a,b, @array,g); • @array = ();
数组(2) • 数组包含元素的个数 • $Size= @array; • 访问数组元素与遍历 • $array[no]; • $array=(1,2,3,4,5); $Element=$array[0]; • foreach $Element(@array){print “$Element”;} • for($i=0; $i <@array;$i++){print “$array[$i]”;} • 其他赋值操作 • ($First)= @array; • ($First,$Second)= @array; • ($First,$Second,@SubAraay)= @array; • @SubAraay = @array[0,1]; • @Array[0,1] = ("string", 46);
数组(3) • 有关数组的操作函数 • push(@Array,$Str) ; #在结尾添加一个元素 • $Str =pop(@Array) ; #在结尾删除一个元素 • unshift (@Array, $Str) ; #在头添加一个元素 • $Str = shift (@Array) ; #在头删除一个元素 • @sorted=sort(@Array); #只有在赋值时有效 • @ reversed=reverse(@Array); #只有在赋值时有效 • @array=split(“; ”,$String); #字符串拆解 • $String =join(“;”, @array); #字符串连接 • chop(@array); #对每个元素去掉最后一个字符 • chomp(@array); #对每个元素去掉最后一个换行符
哈希(1) • 哈希变量 • 以%开头表示哈希变量 • 集合((key1,value1), (key2,value2),… (keym,valuem)) • Key 为数值或者字符串 • Value 为数值、者字符串或者引用 • 哈希的赋值 • %Hash=(); • %Ages = ("Michael Caine", 39, "Dirty Den", 34, "Angie", 27); • @fruit = ("apples",17,"bananas",9,"oranges","none"); %fruitHash = @fruit; • ($var1, $var2, %myarray) = @list • @Key=keys(%hash); • @value=values(%hash); • 访问哈希表 • $ages{"Michael Caine"}; # Returns 39 • $ages{"Dirty Den"}; # Returns 34
哈希(2) • 增加元素 • $hash{$key}=$value; • 删除元素 • delete ($Hash{$Key}); • 查找 • if ( defined $hash{$element} ){print “$hash{$element}”;} • 遍历 foreach $person (keys %ages){print "$person $ages{$person}\n";} foreach $person (sort keys %ages){print "$person $ages{$person}\n";} foreach (sort{$Word{$b} <=> $Word{$a} } keys %Word){ print Out "$_ $Word{$_}\n"; } %records = (“one", 61, “two", 755, “three", 511); while (($holder, $record) = each(%records)) {print "$holder $record \n";}
文件句柄 • 以读方式打开一个文件 open(FH, "< $filename"); • 以写方式打开一个文件 open(FH, "> $filename"); • 以添加方式打开一个文件 open(FH, ">> $filename"); • 关闭文件 close( FH ) • 读文件 While( < FH > ){ print “$_\n”; } @lines=< FH >; • 读文件 print FH “This data is $Value\n”;
引用 • 引用就是指向其他变量的标识。 • 在被引用变量前加\ • 指向简单变量的引用 $Str="data"; $Point=\$Str; • 指向简单变量的引用 @array=("a","b","c"); $Point=\@array; • 指向简单变量的引用 %hash=("a",1,"b",2,"c",3); $Point=\%hash;
使用引用构造复杂数据结构(1) • 二维数组 • @array1=("a","b","c"); • @array2=("d","e","f"); • @array3=("s","t","z"); • @array=(\@array1,\@array2,\@array2); • $Pointer=$array[0]; • print "@$Pointer"."\n"; • print $$Pointer[2]; • print ${$array[0]}[2]; • print "$array[0]->[2]"."\n"; • @array1=(1,2);@array2=("a","b"); • push(@array,\@array1);push(@array,\@array2); • print ${$array[0]}[1],"\n";print ${$array[1]}[1],"\n";
使用引用构造复杂数据结构(2) • 值为哈希的哈希 • %hash1=("a0",11,"b0",12,"c0",13); • %hash2=("a1",21,"b1",22,"c1",23); • %hash3=("a2",31,"b2",32,"c2",33); • %hash=("a",\%hash1,"b",\%hash2,"c",\%hash3); • $Pointer=$hash{"a"}; • @key=sort keys(%$Pointer); • print @key; • print ${$hash{"a"}}{"a0"}; • print $hash{"b"}->{"b1"}; • %Hash1=("a",1,"b",2); • %Hash2=("d",1,"f",2); • $hash{"a"}=\%Hash1; • $hash{"b"}=\%Hash2; • print $hash{"a"}->{"b"},"\n";
使用引用构造复杂数据结构(3) • 值为数组的哈希 • @array1=("a","b","c"); • @array2=("d","e","f"); • @array3=("s","t","z"); • %hash=("a",\@array1,"b",\@array2,"c",\@array3); • $Pointer=$hash{"b"}; • print "@$Pointer"."\n"; • print $hash{"c"}->[2]; • print ${$hash{"b"}}[0]."\n"; • foreach (sort keys %hash){ • $Pointer=$hash{$_}; • foreach ( @$Pointer ){ • print "$_ "; • } • print "\n"; • }
使用引用构造复杂数据结构(4) • 一个混合数据结构 • $Val=12; • $String="data"; • @array=("a","b","c"); • %hash=("a0",11,"b0",12,"c0",13); • @Struct=(\$Val,\$String,\@array,\%hash); • print ${$Struct[0]}."\n"; • print ${$Struct[1]}."\n"; • print $Struct[2]->[2]."\n"; • print $Struct[3]->{"a0"}."\n"; • $Pointer=$Struct[2]; • push(@$Pointer,"d"); • print "@$Pointer"."\n"; • print $Struct[2]->[3]; • $Pointer=$Struct[3]; • ${$Pointer}{"d0"}="14"; • print sort keys (%{$Struct[3]}),"\n"; • print sort values (%{$Struct[3]}),"\n";
模式匹配 • 模式匹配 • 指在字符串中寻找的特定序列的字符。若在该字符串中找到了该模式,则返回true,不匹配则返回false • 语法 • $string=~/pattern/; #在string中查找是否包含模式pattern的字符串 • $string=~m/pattern/; #同上,另外一种表示方法 • 例子 1: $question=“please open the door”; if ($question =~ /please/) { print ("Thank you for being polite!\n"); } else { print ("That was not very polite!\n"); } $string=‘http://www.blu.edu.cn”; if ($question =~ /http:\/\//) { … } else { …} $string=“a b c”; @Array=split(/ /,$string);
模式中的特殊符号(1) • 符号+ • 表示一个或多个相同的字符, @array = split (/ +/, $line); $string=“hoool”; if ( $string=~/o+/ ){ print “$&\n”; } • 字符* • *表示匹配0个,一个或多个相同的字符. $string=“hoool”; if ( $string=~/ho*/ ){ print “$&\n”; } • 字符? • ?表示匹配0个或一个的字符. $string=“hoool”; if ( $string=~/ho?/ ){ print “$&\n”; }
模式中的特殊符号(2) • 字符 []和[^] • []表示一组字符中的一个 $string="aa1bb"; if ( $string=~/a[123]b/ ){ print "$&\n"; } $string="aa123bb"; if ( $string=~/a([123]+)b/ ){ print "$&\n"; } • [^]表示一组字符以外的所有字符 $string="aa123bb"; if ( $string=~/[^ab]+/ ){ print "$&\n"; } • 简写形式 [a-z] [0-9] [A-Z] [0-9a-z] [0-9,a-z,A-Z]
模式中的特殊符号(3) • 转义\ • 在模式中包含通常被看作特殊意义的字符,须在其前加斜线"\"。 $string=‘aa*1bb’; if ( $string=~/a\*/ ){ print "$&\n"; } $string=‘aa/?[+bb’; if ( $string=~/\/\?\[\+/ ){ print "$&\n"; } • 字符. • 表示任意字符 $string='aa/?[+bbz'; if ( $string=~/a(.*)z/ ){ print "$& $1\n"; } $string=‘aa/?[+bb’; if ( $string=~/a(.*)b/ ){ print "$&\n"; }
模式中的特殊符号(4) • 锚模式 if ($varname =~ /^\$[A-Za-z][_0-9a-zA-Z]*$/) { print ("$varname is a legal scalar variable\n"); } elsif ($varname =~ /^@[A-Za-z][_0-9a-zA-Z]*$/) { print ("$varname is a legal array variable\n"); } elsif ($varname =~ /^[A-Za-z][_0-9a-zA-Z]*$/) { print ("$varname is a legal file variable\n"); } else { print ("I don't understand what $varname is.\n"); } open(FileIn,"<dictex.txt"); while($Line=<FileIn>){ chomp($Line); if ($Line=~/^\#(.*)$/){$Word=$1;} if ($Line=~/^Trans:(.*)$/){$mapDict{$Word}=$1;} } close(FileIn); $Word="good"; if ( defined $mapDict{$Word}){ print "$Word=>$mapDict{$Word}\n" } • 模式中使用变量 $pattern = "[\s\t ]+"; @words = split(/$pattern/, $line);
模式中的特殊符号(5) • 字符范围转义 : /[\da-z]/ #匹配任意数字或小写字母。 $string=“这个数为12.34"; if ( $string=~/-?\d+\. \d+/){ print "$&\n"; } $string=“这个数为12.34"; if ( $string=~/^\D+/){ print "$&\n"; }
模式中的特殊符号(6) • 匹配指定数目的字符 {} /de{1,3}f/ #匹配def,deef和deeef; • 选项操作符| /def|ghi/匹配def或ghi if ($number =~ /^-?\d+$|^-?0[xX][\da-fA-F]+$/) { print ("$number is a legal integer.\n"); } else { print ("$number is not a legal integer.\n"); } • 模式匹配选项 • 匹配所有可能的模式(g选项) @matches = "balata" =~ /.a/g; • 将字符串看作单行例 s/a.*bc/s匹配字符串axxxxx \nxxxxbc,但/a.*bc/则不匹配该字符串。 • 在模式中忽略空格x /\d{2} ([\W]) \d{2} \d{2}/x等价于/\d{2}([\W])\d{2}\s\d{2}/。
替换操作符 • s/pattern/replacement/egi; $string="i:love:perl";$string=~s/:/*/; #此时$string="i*love:perl";$string=~s/:/*/g; #此时$string="i*love*perl"; $string="www22cgi44";$string=~s/(\d+)/$1*2/eg; #$string="www44cgi88"; • tr/string/string/; $string="testing";$string=~tr/et/ET/"; #此时$string="TEsTing";$string=~tr/a-z/A-Z/; #此时$stirng="TESTING"; $string="CGI+Perl";$string=~tr/+//; #此时$string="CGI Perl";
替换操作符(例子1) 例子 1 open(FileIn,"<wordPOS.txt"); while(<FileIn>){ chomp; s/(\S+)\/(\S+)/$1/g; print "$_\n"; } close(FileIn);
替换操作符(例子2) 例子 2 open(In,"<perl.html");open(Out,">perl.freq"); while(<In>){ chomp; s/<(([^>])*)>//g; s/ / /g; s/&/&/g; @Words=split(/[\s\t;:]/,$_); foreach (@Words){ if ( length > 0 ){ tr/[A-Z]/[a-z]/; $mapWord{$_}+=1; } } } foreach (sort{$mapWord{$b} <=> $mapWord{$a} } keys %mapWord){ print Out "$_ $mapWord{$_}\n"; } close(In);close(Out);
控制结构 • next for($x=0;$x<10;$x++) { if($x==3){ next; } } • last for($x=0;$x<10;$x++) { if($x==3){ last; } } • unless Unless ( $var >1 ){ } • if $Var=1 if ($var >1) • foreach foreach $element(@array){ print “$element\n”; }
子程序 sub max { my $max = shift(@_); foreach $foo (@_) { $max = $foo if $max < $foo; } return $max; } $bestday = max($mon,$tue,$wed,$thu,$fri); • 通过@_ 数组进行参数传递 • @_[0] = parm1, @_[1] = parm2, etc • 函数内私有变量用my • 最后一个return的值就是子程序的返回值
定义和调用子程序 hello(); sub hello { print "hello!"; }
参数传递 @testit=("a","b"); hello("test",@testit); sub hello { my($File,@Array)=@_; print "$File\n"; print "@Array"; }