如何匹配 Unicode 元音字母?
How to match Unicode vowels?
什么字符 class 或 Unicode 属性 将匹配 Perl 中的任何 Unicode 元音?
错误答案:[aeiouAEIOU]
。 (sermon here,洗衣清单中的第 24 项)
perluniprops 仅提及韩文和印度文的元音。
让我们搁置元音是什么的问题。是的,i
在某些情况下可能不是元音。因此,任何 可以是元音 的字符都可以。
没有这样的属性。
$ uniprops --all a
U+0061 <a> \N{LATIN SMALL LETTER A}
\w \pL \p{LC} \p{L_} \p{L&} \p{Ll}
AHex POSIX_XDigit All Alnum X_POSIX_Alnum Alpha X_POSIX_Alpha Alphabetic Any ASCII
ASCII_Hex_Digit Assigned Basic_Latin ID_Continue Is_IDC Cased Cased_Letter LC
Changes_When_Casemapped CWCM Changes_When_Titlecased CWT Changes_When_Uppercased CWU Ll L
Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Hex X_POSIX_XDigit Hex_Digit IDC ID_Start
IDS Letter L_ Latin Latn Lowercase_Letter Lower X_POSIX_Lower Lowercase PerlWord POSIX_Word
POSIX_Alnum POSIX_Alpha POSIX_Graph POSIX_Lower POSIX_Print Print X_POSIX_Print Unicode Word
X_POSIX_Word XDigit XID_Continue XIDC XID_Start XIDS
Age=1.1 Age=V1_1 Block=Basic_Latin Bidi_Class=L Bidi_Class=Left_To_Right BC=L
Bidi_Paired_Bracket_Type=None Block=ASCII BLK=ASCII Canonical_Combining_Class=0
Canonical_Combining_Class=Not_Reordered CCC=NR Canonical_Combining_Class=NR
Decomposition_Type=None DT=None East_Asian_Width=Na East_Asian_Width=Narrow EA=Na
Grapheme_Cluster_Break=Other GCB=XX Grapheme_Cluster_Break=XX Hangul_Syllable_Type=NA
Hangul_Syllable_Type=Not_Applicable HST=NA Indic_Positional_Category=NA InPC=NA
Indic_Syllabic_Category=Other InSC=Other Joining_Group=No_Joining_Group JG=NoJoiningGroup
Joining_Type=Non_Joining JT=U Joining_Type=U Script=Latin Line_Break=AL
Line_Break=Alphabetic LB=AL Numeric_Type=None NT=None Numeric_Value=NaN NV=NaN
Present_In=1.1 IN=1.1 Present_In=2.0 IN=2.0 Present_In=2.1 IN=2.1 Present_In=3.0 IN=3.0
Present_In=3.1 IN=3.1 Present_In=3.2 IN=3.2 Present_In=4.0 IN=4.0 Present_In=4.1 IN=4.1
Present_In=5.0 IN=5.0 Present_In=5.1 IN=5.1 Present_In=5.2 IN=5.2 Present_In=6.0 IN=6.0
Present_In=6.1 IN=6.1 Present_In=6.2 IN=6.2 Present_In=6.3 IN=6.3 Present_In=7.0 IN=7.0
Present_In=8.0 IN=8.0 SC=Latn Script=Latn Script_Extensions=Latin Scx=Latn
Script_Extensions=Latn Sentence_Break=LO Sentence_Break=Lower SB=LO Word_Break=ALetter WB=LE
Word_Break=LE
在处理 i18n 时最重要的是考虑你实际需要什么,但你甚至没有提到你想要完成的事情。
找元音?那不可能是你真正想要做的。我可以看到用于识别单词中元音 发音 的用途,但它们通常由多个字母组成(例如英语中的 "oo",以及 "in","an"/"en"、"ou"、"ai"、"au"/"eau"、"eu"(法语),它将是语言-具体。
就目前而言,您要求的是全球解决方案,但您是在用当地术语定义问题。您首先需要定义要解决的实际问题。
首先,并不是所有的书面语言都有“元音”。 (例如,中文(Zhōngwén)(书面中文)没有,因为它是表意文字而不是语音。再例如,日语大多没有;它主要使用辅音+元音平假名或片假名音节,例如“ga”,改为“wa”、“tsu”。)
一些书面语言(例如,印地语、孟加拉语、希腊语、俄语)确实有元音,但使用的字符不容易映射到 aeiou。对于此类语言,您必须查找(搜索 metacpan?)或制作查找表以指定哪些字母是“元音”。
但是,如果您要处理任何基于拉丁字母 (abcdefghijklmnopqrstuvwxyz) 的书面语言,即使该语言使用大量变音符号(在 Perl 和 Unicode 圈子中称为“组合标记”)(例如,越南语),您 可以 轻松地将它们映射到“元音”或“非元音”,是的。方法是“规范化为完全分解形式”,然后去除所有组合标记,然后折叠大小写,然后将每个字母与正则表达式 /[aeiou]/ 进行比较。以下 Perl 脚本将使用基于拉丁字母表的任何语言找到大部分或所有“元音”:
#!/usr/bin/perl -CSDA
# vowel-count.pl
use v5.20;
use Unicode::Normalize 'NFD';
my $vcount;
while (<>)
{
$_ =~ s/[\r\n]+$//;
say "\nRaw string: $_";
my $decomposed = NFD $_;
my $stripped = ($decomposed =~ s/\pM//gr);
say "Stripped string: $stripped";
my $folded = fc $stripped;
my @base_letters = split //, $stripped;
$vcount = 0;
/[aeiou]/ and ++$vcount for @base_letters;
say "# of vowels: $vcount";
}
抛开元音的定义和不同语言共享符号但使用方式不同的明显问题,有一种方法可以 define your own property 在 Perl 模式中使用。
定义一个以In
或Is
开头的子程序,并指定其中可以包含的字符。最简单的是一个代码号为一行,或者由水平空格分隔的一系列代码号:
#!perl
use v5.10;
use utf8;
use open qw(:std :utf8);
sub InSpecial {
return <<"HERE";
00A7
00B6
2295\t229C
HERE
}
$_ = "ABC\x{00A7}";
say $_;
say /\p{InForeign}/ ? 'Matched' : 'Missed';
什么字符 class 或 Unicode 属性 将匹配 Perl 中的任何 Unicode 元音?
错误答案:[aeiouAEIOU]
。 (sermon here,洗衣清单中的第 24 项)
perluniprops 仅提及韩文和印度文的元音。
让我们搁置元音是什么的问题。是的,i
在某些情况下可能不是元音。因此,任何 可以是元音 的字符都可以。
没有这样的属性。
$ uniprops --all a
U+0061 <a> \N{LATIN SMALL LETTER A}
\w \pL \p{LC} \p{L_} \p{L&} \p{Ll}
AHex POSIX_XDigit All Alnum X_POSIX_Alnum Alpha X_POSIX_Alpha Alphabetic Any ASCII
ASCII_Hex_Digit Assigned Basic_Latin ID_Continue Is_IDC Cased Cased_Letter LC
Changes_When_Casemapped CWCM Changes_When_Titlecased CWT Changes_When_Uppercased CWU Ll L
Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Hex X_POSIX_XDigit Hex_Digit IDC ID_Start
IDS Letter L_ Latin Latn Lowercase_Letter Lower X_POSIX_Lower Lowercase PerlWord POSIX_Word
POSIX_Alnum POSIX_Alpha POSIX_Graph POSIX_Lower POSIX_Print Print X_POSIX_Print Unicode Word
X_POSIX_Word XDigit XID_Continue XIDC XID_Start XIDS
Age=1.1 Age=V1_1 Block=Basic_Latin Bidi_Class=L Bidi_Class=Left_To_Right BC=L
Bidi_Paired_Bracket_Type=None Block=ASCII BLK=ASCII Canonical_Combining_Class=0
Canonical_Combining_Class=Not_Reordered CCC=NR Canonical_Combining_Class=NR
Decomposition_Type=None DT=None East_Asian_Width=Na East_Asian_Width=Narrow EA=Na
Grapheme_Cluster_Break=Other GCB=XX Grapheme_Cluster_Break=XX Hangul_Syllable_Type=NA
Hangul_Syllable_Type=Not_Applicable HST=NA Indic_Positional_Category=NA InPC=NA
Indic_Syllabic_Category=Other InSC=Other Joining_Group=No_Joining_Group JG=NoJoiningGroup
Joining_Type=Non_Joining JT=U Joining_Type=U Script=Latin Line_Break=AL
Line_Break=Alphabetic LB=AL Numeric_Type=None NT=None Numeric_Value=NaN NV=NaN
Present_In=1.1 IN=1.1 Present_In=2.0 IN=2.0 Present_In=2.1 IN=2.1 Present_In=3.0 IN=3.0
Present_In=3.1 IN=3.1 Present_In=3.2 IN=3.2 Present_In=4.0 IN=4.0 Present_In=4.1 IN=4.1
Present_In=5.0 IN=5.0 Present_In=5.1 IN=5.1 Present_In=5.2 IN=5.2 Present_In=6.0 IN=6.0
Present_In=6.1 IN=6.1 Present_In=6.2 IN=6.2 Present_In=6.3 IN=6.3 Present_In=7.0 IN=7.0
Present_In=8.0 IN=8.0 SC=Latn Script=Latn Script_Extensions=Latin Scx=Latn
Script_Extensions=Latn Sentence_Break=LO Sentence_Break=Lower SB=LO Word_Break=ALetter WB=LE
Word_Break=LE
在处理 i18n 时最重要的是考虑你实际需要什么,但你甚至没有提到你想要完成的事情。
找元音?那不可能是你真正想要做的。我可以看到用于识别单词中元音 发音 的用途,但它们通常由多个字母组成(例如英语中的 "oo",以及 "in","an"/"en"、"ou"、"ai"、"au"/"eau"、"eu"(法语),它将是语言-具体。
就目前而言,您要求的是全球解决方案,但您是在用当地术语定义问题。您首先需要定义要解决的实际问题。
首先,并不是所有的书面语言都有“元音”。 (例如,中文(Zhōngwén)(书面中文)没有,因为它是表意文字而不是语音。再例如,日语大多没有;它主要使用辅音+元音平假名或片假名音节,例如“ga”,改为“wa”、“tsu”。)
一些书面语言(例如,印地语、孟加拉语、希腊语、俄语)确实有元音,但使用的字符不容易映射到 aeiou。对于此类语言,您必须查找(搜索 metacpan?)或制作查找表以指定哪些字母是“元音”。
但是,如果您要处理任何基于拉丁字母 (abcdefghijklmnopqrstuvwxyz) 的书面语言,即使该语言使用大量变音符号(在 Perl 和 Unicode 圈子中称为“组合标记”)(例如,越南语),您 可以 轻松地将它们映射到“元音”或“非元音”,是的。方法是“规范化为完全分解形式”,然后去除所有组合标记,然后折叠大小写,然后将每个字母与正则表达式 /[aeiou]/ 进行比较。以下 Perl 脚本将使用基于拉丁字母表的任何语言找到大部分或所有“元音”:
#!/usr/bin/perl -CSDA
# vowel-count.pl
use v5.20;
use Unicode::Normalize 'NFD';
my $vcount;
while (<>)
{
$_ =~ s/[\r\n]+$//;
say "\nRaw string: $_";
my $decomposed = NFD $_;
my $stripped = ($decomposed =~ s/\pM//gr);
say "Stripped string: $stripped";
my $folded = fc $stripped;
my @base_letters = split //, $stripped;
$vcount = 0;
/[aeiou]/ and ++$vcount for @base_letters;
say "# of vowels: $vcount";
}
抛开元音的定义和不同语言共享符号但使用方式不同的明显问题,有一种方法可以 define your own property 在 Perl 模式中使用。
定义一个以In
或Is
开头的子程序,并指定其中可以包含的字符。最简单的是一个代码号为一行,或者由水平空格分隔的一系列代码号:
#!perl
use v5.10;
use utf8;
use open qw(:std :utf8);
sub InSpecial {
return <<"HERE";
00A7
00B6
2295\t229C
HERE
}
$_ = "ABC\x{00A7}";
say $_;
say /\p{InForeign}/ ? 'Matched' : 'Missed';