刨根问底:Java中的“\p{P}”到底是什么意思

阅读: 评论:0

刨根问底:Java中的“p{P}”到底是什么意思

刨根问底:Java中的“p{P}”到底是什么意思

问题由来:
在代码中看到了Patternpile("\p{P}"),用来识别符号,但是这个正则表达式却不匹配加号+,所以p{P}到底是什么意思呢

谷歌了一下,找到StackOverflow上有人问了一模一样的问题

可是这个问题被关掉了,理由是问题重复,贴出了另一个解释所有正则表达式含义的参考回答

nice try,给出正则表达式的参考回答,此举可以减少重复零散的提问
问题是这个参考回答里面根本没有说p{P}到底是什么意思
(似乎在查正则表达式的时候总会遇到类似的问题,然后每次都会归因于自己没学好正则)

再回去看StackOverflow上的回答,有人贴出了Java文档,说这篇文档中有解释

问题是,并没有啊

文档中提到了p{Punct},是下列符号之一:!"#$%&'()*+,-./:;<=>?@[]^_`{|}~,很好,定义非常清晰。

p{P}会是p{Punct}的缩写吗,可是p{P}是不会匹配+的,而p{Punct}的定义中是包含+
文档中还提到了p{Print},是可打印字符[p{Graph}x20],其中p{Graph}[p{Alnum}p{Punct}],其中[p{Lower}p{Upper}],其中p{Lower}p{Upper}分别是[a-z][A-Z]。好家伙,环环相扣。
所以p{P}p{Punct}还是p{Print}呢,反正Java文档里面没说。

测试一下

Pattern.matches("\p{P}", "+");
Pattern.matches("\p{Punct}", "+");

结果分别是falsetrue,显然p{P}p{Punct}不是一回事

再回到StackOverflow,在Java文档的回复下还有两条回复

If I search the Javadocs I don’t find p{P} just p{Punctuation} and p{Print}. Similarly I searched the referenced answer which is already supposed to answer this question and also don’t find a reference to p{P}

我查找了Java文档,没找到p{P},只找到p{Punctuation}p{Print}。同样,我查找了参考回答,那里面本应有这个问题的答案吧?但是我没找到对于p{P}的解释

The linked question (“What does this regex mean?”) doesn’t specifically mention the punctuation Unicode category, but does state that p is for Unicode categories, which addresses what p means (which is asked in this question). Whether it’s a duplicate depends in part on whether this question is primarily asking for an explanation for p, or what the ‘P’ category is (in which case, this question is actually asking 2 questions, one of which is a duplicate).

链接中的问题(“这个正则表达式是什么意思”)并未明确提及Unicode的标点目录,不过确实说到了p表示Unicode目录,这解决了p是什么意思的问题(这是本问题中问到的)。这个问题是否重复部分取决于这个问题首先是要求解释p,还是要求解释“P目录”是什么(在这种情况下,这个问题实际上是提出了两个问题,其中一个是重复的)。

看来不止我有同样的疑问。
再看这个问题的关闭记录,里面提到StackOverflow社区重新审核了是否要重新开启这个问题,结论是,还是让它保持关闭状态吧,当初关闭它的理由不变。怎么就感觉这个问题这么冤呢?

这时我还发现idea居然能识别p{P}p{Punct}
(这个提示也说明p{P}不是p{Print}


得,Punctuation和Punctuation characters还有区别

既然谁讲也讲不清楚,那就暴力试验一下,p{P}p{Punct}到底会匹配哪些字符

    public static final Pattern P = Patternpile("\p{P}");public static final Pattern PUNCT = Patternpile("\p{Punct}");public static void main(String[] args) {StringBuilder psb = new StringBuilder();StringBuilder punctsb = new StringBuilder();// 穷举所有码点for (int i = Character.MIN_CODE_POINT; i < Character.MAX_CODE_POINT; i++) {String c = String.Chars(i));if (P.matcher(c).find()) {psb.append(c);}if (PUNCT.matcher(c).find()) {punctsb.append(c);}}System.out.println(psb);System.out.println(punctsb);}

输出结果如下,说来差别也是蛮大的

!"#%&'()*,-./:;?@[]_{}¡§«¶·»¿;·՚՛՜՝՞՟։֊־׀׃׆׳״؉؊،؍؛؞؟٪٫٬٭۔܀܁܂܃܄܅܆܇܈܉܊܋܌܍߷߸߹࠰࠱࠲࠳࠴࠵࠶࠷࠸࠹࠺࠻࠼࠽࠾࡞।॥॰૰෴๏๚๛༄༅༆༇༈༉༊་༌།༎༏༐༑༒༔༺༻༼༽྅࿐࿑࿒࿓࿔࿙࿚၊။၌၍၎၏჻፠፡።፣፤፥፦፧፨᐀᙭᙮᚛᚜᛫᛬᛭᜵᜶។៕៖៘៙៚᠀᠁᠂᠃᠄᠅᠆᠇᠈᠉᠊᥄᥅᨞᨟᪠᪡᪢᪣᪤᪥᪦᪨᪩᪪᪫᪬᪭᭚᭛᭜᭝᭞᭟᭠᯼᯽᯾᯿᰻᰼᰽᰾᰿᱾᱿᳀᳁᳂᳃᳄᳅᳆᳇᳓‐‑‒–—―‖‗‘’‚‛“”„‟†‡•‣․‥…‧‰‱′″‴‵‶‷‸‹›※‼‽‾‿⁀⁁⁂⁃⁅⁆⁇⁈⁉⁊⁋⁌⁍⁎⁏⁐⁑⁓⁔⁕⁖⁗⁘⁙⁚⁛⁜⁝⁞⁽⁾₍₎〈〉❨❩❪❫❬❭❮❯❰❱❲❳❴❵⟅⟆⟦⟧⟨⟩⟪⟫⟬⟭⟮⟯⦃⦄⦅⦆⦇⦈⦉⦊⦋⦌⦍⦎⦏⦐⦑⦒⦓⦔⦕⦖⦗⦘⧘⧙⧚⧛⧼⧽⳹⳺⳻⳼⳾⳿⵰⸀⸁⸂⸃⸄⸅⸆⸇⸈⸉⸊⸋⸌⸍⸎⸏⸐⸑⸒⸓⸔⸕⸖⸗⸘⸙⸚⸛⸜⸝⸞⸟⸠⸡⸢⸣⸤⸥⸦⸧⸨⸩⸪⸫⸬⸭⸮⸰⸱⸲⸳⸴⸵⸶⸷⸸⸹⸺⸻、。〃〈〉《》「」『』【】〔〕〖〗〘〙〚〛〜〝〞〟〰〽゠・꓾꓿꘍꘎꘏꙳꙾꛲꛳꛴꛵꛶꛷꡴꡵꡶꡷꣎꣏꣸꣹꣺꤮꤯꥟꧁꧂꧃꧄꧅꧆꧇꧈꧉꧊꧋꧌꧍꧞꧟꩜꩝꩞꩟꫞꫟꫰꫱꯫﴾﴿︐︑︒︓︔︕︖︗︘︙︰︱︲︳︴︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄﹅﹆﹇﹈﹉﹊﹋﹌﹍﹎﹏﹐﹑﹒﹔﹕﹖﹗﹘﹙﹚﹛﹜﹝﹞﹟﹠﹡﹣﹨﹪﹫!"#%&'()*,-./:;?@[\]_{}⦅⦆。「」、・𐄀𐄁𐄂𐎟𐏐𐡗𐤟𐤿𐩐𐩑𐩒𐩓𐩔𐩕𐩖𐩗𐩘𐩿𐬹𐬺𐬻𐬼𐬽𐬾𐬿𑁇𑁈𑁉𑁊𑁋𑁌𑁍𑂻𑂼𑂾𑂿𑃀𑃁𑅀𑅁𑅂𑅃𑇅𑇆𑇇𑇈𒑰𒑱𒑲𒑳
!"#$%&'()*+,-./:;<=>?@[]^_`{|}~

idea还有自动补全提示

这么看来Unicode确实有很多用字母或缩写表示的category,理应是存在一个文档的,不然idea怎么认识呢,不然Java怎么会去实现呢

或许关键词是Unicode category
回到StackOverflow的参考回答,在其中找到了一个叫Unicode categories的链接,链接到了另一个问题:Unicode category L是什么
其中一个回答贴出了一个链接,其中列出了所有的Unicode categories

谷歌一下Unicode categories,找到了维基百科的解释

这些名字越看越眼熟,不就是我两年前看过的东西么,淦

总结一下
p{P}是Unicode定义的,是一个Unicode目录,表示所有的符号,可以细分为Pc、Pd、Pe等等
p{Punct}是Java定义的,是下列符号之一:!"#$%&'()*+,-./:;<=>?@[]^_`{|}~

那么还有最后一个问题
为什么Unicode P目录下不包含加号+

其实也没有为什么,反正Unicode把加号归类到S目录下了(S for Symbol),具体来说是Sm目录(Symbol, math)

刨根问底结束

本文发布于:2024-02-04 19:32:30,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170714837058826.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23