【发布时间】:2013-10-24 04:15:08
【问题描述】:
我正在尝试为 perl webapp 中的名称大写寻找解决方案(使用 perl v5.10.1)。我最初想使用 Lingua::EN::NameCase,但发现重音字符存在一些问题。
我需要能够处理来自各种欧洲语言(爱尔兰语、法语、德语)的重音字符。
我在网上看到一些迹象表明 Lingua::EN::NameCase 应该适用于我的用例。例如,这个关于 perlmonks 的页面:http://www.perlmonks.org/?node_id=889135
这是我基于上述链接的测试代码:
#!/usr/bin/perl
use strict;
use warnings;
use Lingua::EN::NameCase;
use locale;
use POSIX qw(locale_h);
my $locale = 'en_FR.utf8';
setlocale( LC_CTYPE, $locale );
binmode DATA, ':encoding(UTF-8)';
binmode STDOUT, ':encoding(UTF-8)';
while (my $original_name = <DATA>) {
chomp $original_name;
my $normalized_name = nc($original_name);
printf "%30s L::EN::NC %30s UCFIRST %30s\n", $original_name, $normalized_name, xlc($original_name);
}
sub xlc {
my $str = shift;
$_ = lc( $str );
return join q{} => ( map { ucfirst(lc($_)) } ( $str =~ m/(\W+|\w+)/g ) );
};
__DATA__
ÉTIENNE DE LA BOÉTIE
ÉMILIE DU CHÂTELET
HÉLÈNE CIXOUS
Seán Ó Hannracháín
Máire Ó hÓgartaigh
产生下面的输出。 L::EN::NC 和自定义 ucfirst(lc()) 解决方案都会产生不正确的结果(注意每个重音字符后面的大写字母)。这似乎是因为 perl 正则表达式在每个重音字符之前/之后匹配“单词边界”。我希望单词边界只匹配空格字符和非空格字符。
有人可以提出解决方案吗?
谢谢,
布赖恩。
ÉTIENNE DE LA BOÉTIE L::EN::NC éTienne de la BoéTie UCFIRST ÉTienne De La BoÉTie
ÉMILIE DU CHÂTELET L::EN::NC éMilie du ChâTelet UCFIRST ÉMilie Du ChÂTelet
HÉLÈNE CIXOUS L::EN::NC HéLèNe Cixous UCFIRST HÉLÈNe Cixous
Seán Ó Hannracháín L::EN::NC SeáN ó HannracháíN UCFIRST SeÁN ó HannrachÁíN
Máire Ó hÓgartaigh L::EN::NC MáIre ó HóGartaigh UCFIRST MÁIre ó HÓGartaigh
【问题讨论】:
-
hwnd 发布的链接很有趣,但
$original_name上的 utf8 标志 已设置:一切都已正确解码。 -
确实如此。我对大写本身没有问题。 uc() 和 lc() 似乎在我发送给他们的任何字符串上都可以正常工作。问题是 L::EN::NC 似乎无法正确识别单词的开头,以便将该单词的第一个字母大写。 L::EN::NC 中的相关正则表达式是
s{ \b (\w) }{\u$1}gox ;,它使用\b来识别单词边界。对我来说\b似乎将重音字符和非重音字符之间的任何变化识别为单词边界,这对我来说似乎是错误的。 -
Perl Unicode test on OS X fails on Debian 的可能副本——但我不太确定。
en_*.*-locale 根本不认为é在\w中。 -
@amon,感谢您的跟进。你指出我的问题似乎是同一个问题,并让我开始思考为什么某些语言环境不会将
é视为在\w中。长话短说,将原始示例中的语言环境更改为en_IE或fr_FR解决了原始问题。在另一个问题中对 perlre 的引用使我相信use feature 'unicode_strings'可能也解决了我的问题(通过将重音字符视为 \w 的一部分),但我没有足够新的 perl 来使用该功能。
标签: regex perl unicode capitalization