[老贴整理]如何使用正则式从英文句子里提取词根
以前在chinaunix回答过这样一个问题,用到了正则表达式(而且我认为正则式解决此类问题是最合适的。)
学英语的一些例句,每句都有若干词根相同的词,例如 She swears to wear the pearls that appear to be pears. 但是每句的词根都未必相同;我希望把这些包含词根的词都标记出来,请问如何写?
这里说的词根不是原本词根的定义,只是一组字母序列,比如
9. The dust in the industrial zone frustrated the industrious man.
词根是dust或ust
10. The just budget judge just justifies the adjustment of justice.
词根是dust
11. I used to abuse the unusual usage, but now I’m not used to doing so.
词根是use,有变形
12. The lace placed in the palace is replaced first, and displaced later.
词根是lace
13. I paced in the peaceful spacecraft.
词根是pace
14. Sir, your bird stirred my girlfriend’s birthday party.
词根是ir
如果您对此问题感兴趣,请独立思考后再继续阅读本站提供的解决方法。
我的思路是,既然每行句子的结构是一致的,依靠循环就能解决所有问题。因此只要分析一句即可。对于每一句,需要每个单词进行逐个分析。
对第一句作手术分析。
She swears to wear the pearls that appear to be pears.
人的眼睛一下子就能看出ear是词根。但是,就跟《1984》里面2+2=?这个含义深刻的式子一样,如何证明它等于几,才是问题所在。
我把自己想像成正则式机器人。我可以一句一句地读取原文。(perl 语法:while(<FILE>)),然后可以读取每个单词来分析(perl语法:\w+表示每个单词)。对于每个单词的任意N(N最小为3,最大为该词词长)个连续字母(记作$matchstr),在整句中检验其出现的次数,将此“词根”和出现次数保存在hash表中。hash表在此的作用是:如果该词根没有记录,则创建该记录,并自动加1。
思路如下。
- 对于每1行
- 对于每个单词
- 对于这个单词的任意连续3-N个字母,检查其在文本行中出现的频率M,记录在HASH表中。
- 对HASH表的值进行排序。取出最大的个一。打印输出。
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 | #!/usr/bin/perl -w $/ = ".\n"; while (<>) { my @array=""; my %myhash=(); print "---------------------------\n"; print "the line is :$_\n"; while(/^\w+/) { s/^(\w+)\W+(.*)$/$2/; push(@array,lc($1)); #save all the words(in lower case format) into array. } @b=@array; #copy this array to b, for checking my $len; my $matchlen; foreach $item(@array) { $len=length($item); for( $matchlen=$len;$matchlen>=3;$matchlen--) { for( $i=0;$i<=$len-$matchlen;$i++) { $matchstr=substr($item,$i,$matchlen); #define the matchstring. foreach $pig(@b) { next if ( $item eq $pig); #the word can not match against itself. if ( $pig =~ /$matchstr/) { $myhash{$matchstr}++; #if matches, record them. } } } } } foreach (keys %myhash) { print "$_:$myhash{$_};\t"; #print all the successful match records. } print "\n"; } |
注:本站使用了WP-CODEBOX Plugin,您可以参考此处格式在评论中加入代码。
/(\w{2,})(?=(?:.*\1){2,})/[Reply]