从UTF8文本中提取小写的俄语单词

时间:2013-03-11 14:55:09

标签: perl unicode utf-8 text-extraction utf

在Windows 7上使用ActiveState Perl 5.14.2或在CentOS 6.3 Linux上使用Perl 5.10.1我试图从UTF8文本中提取所有小写的单词:

#!/usr/bin/perl -w

use strict;
use warnings;

while(<>) {
    # print "$1\n" while /\b([a-z]{3,})\b/g;
    print "$1\n" while /\b([\x{0430}-\x{044F}]{3,})\b/g;
}

虽然这适用于英语单词(请参阅上面的注释行),但这对于西里尔语单词来说是失败的(请参阅the Unicode range chart) - 脚本不会打印任何内容。

有人请知道,出了什么问题?

为方便起见,下面粘贴了俄语文本示例:

  

ВсесмешалосьвдомеОблонских。 Женаузнала,чтомужбылвсвязис   бывшеювихдомефранцуженкою-гувернанткой,иобъявиламужу,чтоне   можетжитьснимводномдоме。 Положениеэтопродолжалосьужетретий   деньимучительночувствовалосьисамимисупругами,ивсемичленами   семьи,идомочадцами。

2 个答案:

答案 0 :(得分:2)

您引用的范围&gt; 255(\x{0430}),这是内部Perl unicode格式。但是你的字符串似乎没有转换成那种格式。您需要设置use utf8; pragma。这对我有用:

#!/usr/bin/perl -w

use strict;
use warnings;
use utf8;

binmode(STDOUT, ":utf8"); #Fix stdout warning

while(<DATA>) {
    print lc($1)."\n" while /\b([\x{0430}-\x{044F}]{3,})\b/g;
}
__DATA__
Все смешалось в доме Облонских. Жена узнала, что муж был.
в связи с бывшею в их доме француженкою-гувернанткой, и объявила мужу, что не может жить с ним в одном доме.
Положение это продолжалось уже третий день и мучительно чувствовалось и самими супругами, и всеми членами семьи, и домочадцами.

但更正确的方法是操作字符,而不是范围。此外,如果您从某个文件中读取,则可能需要设置utf8标志:

#!/usr/bin/perl -w

use strict;
use warnings;
use utf8;

binmode(STDOUT, ":utf8");

while(<>) {
    utf8::decode($_); #Convert into internal utf8 format
    print lc($1)."\n" while /\b([а-яА-ЯёЁ]{3,})\b/g;
}

Файл:

Однажды в студёную зимнуюю пору... ёёёёЁЁЁ йййЙЙЙЙ
Приветт, земляк!

如果你启用use utf8 lc()会知道小写字母。

ёЁ是分开的,它是变音符号,不适合范围)

答案 1 :(得分:0)

您需要将STDIN和STDOUT设置为UTF-8:

binmode STDOUT, ':utf8';
binmode STDIN, ':utf8';

你的正则表达式应该在此之后工作。

那就是说,我会使用Unicode属性测试的组合而不是显式范围:

\b(((?=\p{Cyrillic})\p{Lowercase_Letter}){3,})\b
相关问题