1

Windows7でActiveStatePerl5.14.2を使用するか、CentOS6.3LinuxでPerl5.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;
}

これは英語の単語ではうまく機能しますが(上記のコメント行を参照)、キリル文字では失敗します(Unicode範囲チャートを参照してください)。スクリプトでは何も出力されません。

誰か知っていますか、何が問題なのですか?

便宜上、ロシア語のサンプルテキストを以下に貼り付けています。

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

4

2 に答える 2

2

\x{0430}内部Perlユニコード形式である255()を超える範囲を参照しています。しかし、あなたの文字列はその形式に変換されていないようです。use utf8;プラグマを設定する必要があります。これは私のために働きます:

#!/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()を有効にすると、小文字になります。

ёЁ分離されたcusそれはumlautであり、範囲に収まりません)

于 2013-03-11T15:18:28.353 に答える
0

STDINとSTDOUTをUTF-8に設定する必要があります。

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

この後、正規表現は機能するはずです。

そうは言っても、明示的な範囲の代わりにUnicodeプロパティテストの組み合わせを使用します。

\b(((?=\p{Cyrillic})\p{Lowercase_Letter}){3,})\b
于 2013-03-11T15:03:48.077 に答える