perl webapp(perl v5.10.1を使用)で名前を大文字にするソリューションを探しています。もともと私はLingua :: EN :: NameCaseを使うと思っていましたが、アクセント付きの文字にはいくつかの問題があります。アクセント付き文字を含む文字列を大文字にする
さまざまなヨーロッパ言語(アイルランド語、フランス語、ドイツ語)のアクセント付き文字に対応できる必要があります。
私はLingua :: EN :: NameCaseが私のusecaseのために動作するはずのいくつかの兆候を見ました。例えば、perlmonks上のこのページ:
#!/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
以下の出力を生成します。http://www.perlmonks.org/?node_id=889135
ここでは、上記のリンクに基づいて、私のテストコードがあります。 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
参照[Perlで大文字アクセント付き文字](http://stackoverflow.com/questions/13261522/uppercase-accented-characters-in-perl) – hwnd
リンクしているページhwndは面白いですが、utf8フラグ*は '$ original_name'に設定されています:すべてが正しくデコードされています。 – amon
確かに。大文字小文字の問題はありません。 uc()とlc()は、私がそれらに送るどの文字列でもうまく動作するようです。問題はL :: EN :: NCがその単語の最初の文字を大文字にするために単語の先頭を正しく識別できないように見えることです。 L :: EN :: NCに関連する正規表現は単語境界を識別するために '\ b 'を使用する' {\ b(\ w)} {\ u $ 1} gox; 'です。私にとっては、 '\ b'はアクセント付きの文字とアクセントのない文字の間の変化を単語の境界として識別しているようです。 –