以前の質問からロケールプラグマの下で単語の文字が一致しないのはなぜですか?ネストされた引用符を変更する方法UTF-8データを処理する場合\w
、word-charとして信頼することはできず、Unicode文字プロパティを使用する必要があることを学びました\p{Word}
。現在、ゼロ幅の単語境界\b
もUTF-8(ロケールが有効になっている)では機能しないことがわかりましたが、Unicode文字プロパティに同等のものは見つかりませんでした。私はそれを自分で次のように構築できると思いました:(?<=\P{Word})(\p{Word}+)(?=\P{Word})
、それはと同等でなければなりません\b(\w+)\b
。
以下のテストスクリプトには、2つの異なる正規表現をテストするための2つの配列があります。\b
ロケールが有効になっていない場合、最初のベースは正常に機能します。ロケールでも機能するように、境界をエミュレートする別のバージョンを作成し(?=\P{Word})
ましたが、期待どおりに機能しません(スクリプトでも期待される結果を示しています)。
何が問題で、エミュレートされた正規表現を最初にASCIIで(またはロケールなしで)機能させる方法がわかりますか?
#!/usr/bin/perl
use 5.010;
use utf8::all;
use locale; # et_EE.UTF-8 in my case
$| = 1;
my @test_boundary = ( # EXPECTED RESULT:
'"abc def"', # '«abc def»'
'"abc "d e f" ghi"', # '«abc «d e f» ghi»'
'"abc "d e f""', # '«abc «d e f»»'
'"abc "d e f"', # '«abc "d e f»'
'"abc "d" "e" f"', # '«abc «d» «e» f»'
# below won't work with \b when locale enabled
'"100 Естонiï"', # '«100 Естонiï»'
'"äöõ "ä õ ü" ï"', # '«äöõ «ä õ ü» ï»'
'"äöõ "ä õ ü""', # '«äöõ «ä õ ü»»'
'"äöõ "ä õ ü"', # '«äöõ «ä õ ü»'
'"äöõ "ä" "õ" ï"', # '«äöõ «ä» «õ» ï»'
);
my @test_emulate = ( # EXPECTED RESULT:
'"100 Естонiï"', # '«100 Естонiï»'
'"äöõ "ä õ ü" ï"', # '«äöõ «ä õ ü» ï»'
'"äöõ "ä õ ü""', # '«äöõ «ä õ ü»»'
'"äöõ "ä õ ü"', # '«äöõ "ä õ ü»'
'"äöõ "ä" "õ" ï"', # '«äöõ «ä» «õ» ï»'
);
say "BOUNDARY";
for my $sentence ( @test_boundary ) {
my $quote_count = ( $sentence =~ tr/"/"/ );
for ( my $i = 0 ; $i <= $quote_count ; $i += 2 ) {
$sentence =~ s/
"( # first qoute, start capture
[\p{Word}\.]+? # suva word-char
.*?\b[\.,?!»]*? # any char followed boundary + opt. punctuation
)" # stop capture, ending quote
/«$1»/xg; # change to fancy
}
say $sentence;
}
say "EMULATE";
for my $sentence ( @test_emulate ) {
my $quote_count = ( $sentence =~ tr/"/"/ );
for ( my $i = 0 ; $i <= $quote_count ; $i += 2 ) {
$sentence =~ s/
"( # first qoute, start capture
[\p{Word}\.]+? # at least one word-char or point
.*?(?=\P{Word}) # any char followed boundary
[\.,?!»]*? # optional punctuation
)" # stop capture, ending quote
/«$1»/gx; # change to fancy
}
say $sentence;
}