在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) - 脚本不会打印任何内容。
有人请知道,出了什么问题?
为方便起见,下面粘贴了俄语文本示例:
ВсесмешалосьвдомеОблонских。 Женаузнала,чтомужбылвсвязис бывшеювихдомефранцуженкою-гувернанткой,иобъявиламужу,чтоне можетжитьснимводномдоме。 Положениеэтопродолжалосьужетретий деньимучительночувствовалосьисамимисупругами,ивсемичленами семьи,идомочадцами。
答案 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