作者TKB5566 (蔡英文还我七天假!!)
看板java
标题Re: [问题] 使用正则表示式?
时间Mon May 8 21:28:18 2023
藉这个标题回一下,关於regular expression,应该是先理解其本身的基本观念,
接着再延伸到各个程式语言对regular expression的应用与变形,例如Java、JavaScript
所以一开始对regular expression的理解会是这样:
[0123456789]
[9876543210]
[0-9]
\d
(1|2|3|4|5|6|7|8|9)
以上五种写法都是表达同一种意思,即任一个数字字元。
那麽为何[0-9]可以,[9-0]就不可以呢?
因为若是采用[0-9]这种含有范围字元的写法,范围字元左右两边,对应的ascii code
必须是小跟大;0的ascii code是48,9的ascii code是57,所以必须写成[0-9]才行。
也就是说,大原则上regular expression底层是会被转换成ascii code来执行。
或是这样理解:
/d/D
/s/S
/w/W
.(加上空白字元)
以上四种写法也都是一样意思,表示任何一个字元;而
[0-9A-Za-z_]包含所有英数字元,也就是上面四种写法减去部分特殊字元。
以上都是表达单一字元,若要表达多个字元,比方说4个数字字元。写法可以是:
[0-9][0-9][0-9][0-9]
[0-9]{4}
\d\d\d\d
\d{4}
甚至是
(1|2|3|4|5|6|7|8|9)重复写4次。
可以看到不同语法的组合,可以产生很多种写法。
而一个/一串字元,至少出现0次、至少出现1次、0或1次也都有对应的写法:*、+、?。
另外还有否定意思的写法:^;[^a]就是非a;[^ab]就是第一个字元非a,或是非b。
而
[a^b]和[\^ab]都是一样的意思,都是a、^、b三个字元任一即可。
------------------------------------------------------------
以上是regular expression最基本的观念与原则。而Java的regular expression,
采用的是ascii编码,正好和上面讲到的原则,底层由ascii code执行一样。
也就是说上面提到的
[0-9]写法,在Java是可以的,但[9-0]这种写法就不行了。
另一个Java常见的regular expression状况,是必须将\d \D \s \S \w \W这些写法,
改成改成\\d \\D \\s \\S \\w \\W。原因是避免Java在执行时,误以为
\d \D \s \S \w \W是跟\n \t一样类型的字元,或者是说
避免\被Java当作跳脱字元。
所以\才要写成\\。
那这样的话,若是要在Java,表达单纯一个\这样的字元,该如何表示?
先尝试写出\的regular expression,
单纯一个\,会跟\d \D的\搞混,所以要改写成\\;\\就是regular expression
表达一个\的写法。然後\\这个写法要写在Java程式上;
前面说过,
Java看到一个\,就会当成是一个跳脱字元,那现在有两个\,
Java就会认为是两个跳脱字元,这样的话就要加上两次\,避免两个\都被当成跳脱字元,
就变成\\\\。
-------------------------------------------
以上是根据
https://www.tenlong.com.tw/products/9789865005047
这本书来简单分享,有错的话希望不要编得太大力= =。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 49.216.22.152 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1683552503.A.B1F.html
1F:→ ssccg: 後那段「Java的写法」其实是Java literal string的写法 05/09 08:14
2F:→ ssccg: 在literal string里需要escape \,实际的string物件里就跟 05/09 08:16
3F:→ ssccg: 原本的regex是一样的,如果是用别的方式输入例如档案就不需 05/09 08:17
4F:→ ssccg: 要\\ 05/09 08:17
5F:推 EijiHoba: 谢谢分享 08/10 08:50