使用Pattern p = Pattern.compile("\\p{Punct}");
时,\p{Punct}
表示以下32个字符:
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
参考:the Pattern
class.
这32个字符对应于ASCII字符集字符0x21
到0x7e
,不包括字母和数字.它们还碰巧代表了我的标准美国键盘上的所有非字母和非数字符号(当然,您的键盘可能不同).
严重的口音(也被称为倒勾音)就在那个列表和我的键盘上.
这是一个"预定义字符类"的简单示例,并解释了m.matches()
返回true
的原因.
当你添加Pattern.UNICODE_CHARACTER_CLASS
个标志时,事情会变得更复杂.
正如该标志的documentation所解释的,它:
Enables the Unicode version of Predefined character classes and POSIX character classes.
以及:
When this flag is specified then the (US-ASCII only) Predefined character classes and POSIX character classes are in conformance with Unicode Technical Standard #18: Unicode Regular Expressions Annex C: Compatibility Properties.
查看上面提到的Annex C个,我们发现一个表格显示了"兼容性属性名称的推荐分配".
对于我们的房产名称(punct
),标准建议使用以下定义的字符:
\p{gc=Punctuation}
这里,"gc"代表"一般类别".Unicode字符被分配一个"general category"的值.在本例中,即Punctuation
——也缩写为P
,并进一步细分为各种子类别,例如Pc
表示连接器,Pd
表示破折号,等等.还有一个"其他标点符号"的总括Po
.
在Unicode中,grave字符被分配到Symbol
个一般类别,以及Modifier
个子类别.你可以看到分配给Sk
here的任务.
将其与ASCII感叹号等字符进行对比(这也是我们最初的\p{Punct}
列表的一部分,如上所示).对于we can see,一般类别分配为Po
.
这就解释了为什么当我们把Pattern.UNICODE_CHARACTER_CLASS
面旗帜添加到原始图案中时,坟墓不再匹配.
它被分配到与我们在正则表达式中使用的标点符号类别不同的一般类别.
显而易见的下一个问题是why did the grave character not get included in the Unicode 100 general category?为什么改为Sk
?
对此,我没有一个好的答案——我肯定有"历史原因".然而,值得注意的是,这Sk
个系列包括尖锐口音、塞迪利亚口音、迪亚瑞斯口音等等——以及(如前所述)我们的严肃口音.
所有这些都是变音符号——通常与基本字母结合使用来改变发音.所以这可能就是根本原因.
坟墓可能有点奇怪,因为它除了用作变音符号外,还有一个历史用法.
首先,询问坟墓如何成为原始ASCII字符集的一部分可能更为相关.维基百科backtick年版提供了一些相关背景信息.