從我以前的問題Why under locale-pragma word characters do not match?和How to change nested quotes我瞭解到,在處理UTF-8數據時,您不能信任\w
作爲word-char,並且您必須使用Unicode字符屬性\p{Word}
。現在我處於一種情況,我發現零寬度的文字邊界\b
也不支持UTF-8(啓用區域設置),但我在Unicode字符屬性中找不到任何等效字符。我想我可以自己構建它,如:(?<=\P{Word})(\p{Word}+)(?=\P{Word})
,它應該相當於\b(\w+)\b
。如何在使用unicode字符屬性時模擬字邊界?
在下面的測試腳本中,我有兩個數組來測試兩個不同的正則表達式。當區域設置未啓用時,基於\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;
}
首先,是錯誤的:'\ w'和'\ p {word}'在定義上是相同的。但第二,***請請,請不要使用'use locale'雜注。它是破碎的,不可靠的,不可預知的,並且在對接中發生了皇家的痛苦 - 正如你似乎已經發現的那樣。你應該使用'Unicode :: Collate :: Locale'模塊。你可能不應該使用'use utf8:all',而是做你想要的具體事情。 – tchrist 2013-02-23 01:40:15
@tchrist:'\ w'和'\ p {Word}'可能被定義爲相同的,但它們在'use locale'下的行爲不同。當然,當我有其他方式時,我不會使用區域設置。 '使用utf8 :: all'可以很好地滿足我的需求,而且它是顯示我的意圖的乾淨方式。如果utf8 :: all中有一些缺失,也許你可以將它指向作者? – 2013-02-23 12:05:38
你不知道'utf8:all'做了什麼或不做什麼,這正是問題所在 - 我注意到一個問題,不能通過添加東西來解決。你得到了什麼級別的'utf8'警告?沒有或警告或致命?那麼這三種亞型,nonchar和替代品以及non_unicode呢?這些東西應該在代碼中明確,以便人們可以看到它們是什麼。然後在輸入和NFC上輸出到NFD的問題;它是這樣做的嗎? – tchrist 2013-02-23 14:59:57