从我以前的问题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