作者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/m.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