w 是不是匹配 Unicode 标准中定义的所有字母数字字符?
Posted
技术标签:
【中文标题】\w 是不是匹配 Unicode 标准中定义的所有字母数字字符?【英文标题】:Does \w match all alphanumeric characters defined in the Unicode standard?\w 是否匹配 Unicode 标准中定义的所有字母数字字符? 【发布时间】:2011-07-30 03:53:54 【问题描述】:Perl 的 \w
是否匹配 Unicode 标准中定义的所有字母数字字符?
例如,\w
会匹配所有(比如)中文和俄文字母数字字符吗?
我编写了一个简单的测试脚本(见下文),它表明 \w
确实与我测试的非 ASCII 字母数字字符“按预期”匹配。但测试显然远非详尽。
#!/usr/bin/perl
use utf8;
binmode(STDOUT, ':utf8');
my @ok;
$ok[0] = "abcdefghijklmnopqrstuvwxyz";
$ok[1] = "éèëáàåäöčśžłíżńęøáýąóæšćôı";
$ok[2] = "şźüęłâi̇ółńśłŕíáυσνχατςęςη";
$ok[3] = "τσιαιγολοχβςανنيرحبالтераб";
$ok[4] = "иневоаслкłјиневоцедањеволс";
$ok[5] = "рглсывызтоμςόκιναςόγο";
foreach my $ok (@ok)
die unless ($ok =~ /^\w+$/);
【问题讨论】:
【参考方案1】:perldoc perlunicode 说
正则表达式中的字符类匹配字符而不是字节,并匹配 Unicode 属性数据库中指定的字符属性。例如,
\w
可用于匹配日语表意文字。
所以看起来你的问题的答案是“是”。
但是,您可能希望使用\p
构造直接访问特定的Unicode character properties。您可能可以使用\pL
(或更短的\pL
)来表示字母,使用\pN
来表示数字,这样您就会更有信心得到您想要的。
【讨论】:
请注意,这取决于字符语义;如果您的字符串来自使用字节语义的源,\w
将仅匹配 ASCII 单词字符。
有关 Unicode 字符语义的更多详细信息,请参阅The Unicode Bug in perlunicode。与\w
等效的保险箱是使用\pAlnum
。
@cjm, \w
实际上是\pWord
。 \pAlnum
缺少下划线。
@Anomie:还有语言环境问题。
@CanSpice:“字母”!=“字母”。您绝不能使用\pL
来表示\pAlphabetic
。他们真的很不一样。从 Unicode 6 开始,有 1006 个代码点具有 Alphabetic 属性但缺少 GC=Letter 属性。【参考方案2】:
是和不是。
如果你想要所有字母数字,你想要[\pAlphabetic\pGC=Number]
。 \w
包含更多和更少。它特别排除了任何\pN
既不是\pNd
也不是\pNl
,如上标、下标和分数。这些是\pGC=Other_Number
,不包含在\w
中。
因为与大多数正则表达式系统不同,Perl 遵守 Requirement 1.2a, “Compatibility Properties” 来自 UTS #18 on Unicode Regular Expressions,然后 假设您有 Unicode 字符串, 正则表达式中的 \w
匹配任何单个代码点以下四个属性:
\pGC=Alphabetic
\pGC=Mark
\pGC=Connector_Punctuation
\pGC=Decimal_Number
上面的数字 4 可以用以下任何一种方式表示,它们都被认为是等价的:
\pDigit
\pGeneral_Category=Decimal_Number
\pGC=Decimal_Number
\pDecimal_Number
\pNd
\pNumeric_Type=Decimal
\pNt=De
请注意,\pDigit
与 \pNumeric_Type=Digit
不同。例如,代码点 B2,SUPERSCRIPT TWO,只有 \pNumeric_Type=Digit
属性,而不是普通的 \pDigit
。那是因为它被认为是\pOther_Number
或\pNo
。但是,它确实具有您想象的 \pNumeric_Value=2
属性。
确实是上面的第 1 点,\pAlphabetic
,这给人们带来了最大的麻烦。那是因为他们经常错误地认为它与\pLetter
(\pL
) 相同,但事实并非如此。
Alphabetics 包括的远不止这些,都是因为 \pOther_Alphabetic
属性,因为这反过来
包括一些但不是所有\pGC=Mark
、所有\pLowercase
(与\pGC=Ll
不同,因为它添加了\pOther_Lowercase
)和所有\pUppercase
(不同为\pGC=Lu
,因为它添加了\pOther_Uppercase
)。
这就是它如何像罗马数字一样引入\pGC=Letter_Number
所有带圆圈的字母,类型为\pOther_Symbol
和\pBlock=Enclosed_Alphanumerics
。
您不高兴我们使用\w
吗? :)
【讨论】:
“其他字母”包含 GC=Mark 有什么意义? “小写”与 GC=Ll 不一样,这有什么意义?莫名其妙。【参考方案3】:特别是\w
也匹配下划线字符。
#!/usr/bin/perl -w
$name = 'Arun_Kumar';
($name =~ /\w+/)? print "Underscore is a word character\n": print "No underscores\n";
$ underscore.pl
下划线是单词字符。
【讨论】:
以上是关于w 是不是匹配 Unicode 标准中定义的所有字母数字字符?的主要内容,如果未能解决你的问题,请参考以下文章