java正则匹配英文句号_「正则表达式」王国奇遇记
第一回 初來乍到
NPC: "歡迎來到正則表達式的國度,勇士!這里的每一個人都使用正則表達式,我是這里的 NPC,每一個來到這里的人都將由我代為介紹正則世界的規則,至于能領悟到何種境界,就看你的造化了。祝你好運,勇士!"
你:"啊,好的,正則表達式......有點奇怪的名字,它是什么呢?"
NPC:"什么?你還沒有聽過正則表達式,真是一個莽撞的小伙子。看來你也和外面世界的人一樣,每次只有用到字符串匹配 時,才會通過「谷鴿」來我們的國度尋找答案。一群知其然不知其所以然的家伙。"
說著,NPC 身前浮現出幾個鎏金大字:
正則表達式:用來匹配一系列符合某個規則的字符串的表達式。"正則的意思是正規、規則。正則表達式的英文名是 Regular Expression,可以直譯為描述某種規則的表達式,一般縮寫為 regex" ,NPC 緩緩說道。
第二回 牛刀小試
NPC:"我先來考考你吧:你如何判斷一個字符串是不是有效的電話號碼?這可是一個非常常見的需求。"
你:"沒問題,我以前確實寫過一份類似的代碼。首先判斷字符串是否是 11 位,再判斷每一位是否都是數字就可以了。"
public static boolean isValidPhoneNumber(String number) {// 判斷是否是 11 位if (number.length() != 11) return false;// 判斷每一位是否全為數字for (int i = 0; i < number.length(); i++) {if (number.charAt(i) < '0' || number.charAt(i) > '9') return false;}return true; }NPC:"好了好了,快把你這份代碼藏好,這份代碼放到我們正則的國度是會被笑掉大牙的。看看我們國度的人是怎么實現這份需求的吧!"
public static boolean isValidPhoneNumber(String number) {return number.matches("d{11}"); }你:"啊?如此簡潔的實現,正則強者竟恐怖如斯!"
NPC:"這可不是什么強者寫的代碼,充其量算是牛刀小試罷了。"
第三回 初窺門徑
NPC:"我先給你講講正則表達式的精確匹配。一個普通的字符串,比如 abc,它如果用來做正則表達式匹配的話,只能匹配自己。也就是說它只能匹配字符串 abc,不能匹配 ab,Abc 等其他任何字符串。"
System.out.println("abc".matches("abc")); // 輸出為 true System.out.println("ab".matches("abc")); // 輸出為 false System.out.println("Abc".matches("abc")); // 輸出為 false你:"這好像沒什么用,需要精確匹配的話,我們可以用String.equals()函數,不需要用正則吧?"
NPC:"沒錯,正則表達式的精確匹配很少用到。我只是在給你介紹正則表達式的一條基本規則而已。"
NPC:"如果需要匹配的字符串含有特殊字符,那就需要用 轉義。比如 a&b,在用正則表達式匹配時,需要使用 a&b,又由于在 Java 字符串中, 也是特殊字符,它也需要轉義,所以 a&b 對應的 Java 字符串是 a&b,它是用來匹配 a&b 的。"
System.out.println("a&b".matches("a&b")); // 輸出為 true你:"這么說來,這兩個反斜杠的意義竟然還不一樣:一個是正則的轉義,一個是 Java 字符串的轉義。那么我們之前那個匹配電話號碼的例子里面,d的本意也是d嗎?"
NPC:"不錯不錯,算你還有點悟性。d在正則表達式中表示匹配任意數字,d 是 digital 的簡寫。比如00d就可以匹配000,007,008等等。"
你:"那么,00d可以匹配0066嗎?"
NPC:"不能,d只能匹配單個數字。"
你:"那我要怎么才能匹配多個數字呢?"
NPC:"你可以寫多次,比如dd就能匹配兩個數字,ddd能匹配三個數字,需要匹配幾個數字就寫幾次就行了。"
System.out.println("1".matches("dd")); // 輸出為 false System.out.println("11".matches("dd")); // 輸出為 true System.out.println("111".matches("dd")); // 輸出為 false你:"那我如果要匹配 10000 個數字呢?總不能寫一萬次吧?"
NPC:"那就像我們剛才匹配電話號碼的例子一樣,在 d 后面打上花括號 {},{n} 表示匹配 n 次。d{10000} 就表示匹配 10000 個數字。"
你:"原來如此,現在我能完全看懂剛才寫的匹配電話號碼的例子了!"
NPC:"趁熱打鐵,如果要匹配 n ~ m 次,用 {n,m} 即可,如果要匹配至少 n 次,用 {n,} 即可。需要注意 , 后不能有空格。"
System.out.println("1".matches("d{1,2}")); // 輸出為 true System.out.println("12".matches("d{1,2}")); // 輸出為 true System.out.println("123".matches("d{1,2}")); // 輸出為 falseSystem.out.println("123".matches("d{2,}")); // 輸出為 true"按照這個寫法,如果要匹配最多m次,是不是用{,m}? "你若有所思。
NPC:"剛夸了你有點悟性又被你蠢哭了,最多 m 次需要這么寫嗎?直接用{0,m}不就行了嗎?只是因為正無窮不好表示我們才用的{n,},在正則國度根本沒有{,m}這樣的寫法。 "
你:"啊,原來如此,我想多了。"
第四回 小有所成
NPC:"正則的基礎規則中,除了d,還有w和s,w 是 word 的簡寫,表示匹配一個常用字符,包括字母、數字、下劃線。s 是 space 的簡寫,表示匹配一個空格,包括三種:
- 空格鍵打出來的空格
- Tab 鍵打出來的空格
- 回車鍵打出來的空格"
你:"Tab 鍵打出來的空格和回車鍵打出來的空格?是指t和n嗎?"
NPC:"完全正確。"
你:"我明白了,我來測試一下。"
System.out.println("LeetCode_666".matches("w{12}")); // 輸出為 true System.out.println("t n".matches("s{3}")); // 輸出為 true System.out.println("LeettCode 666".matches("w{4}sw{4}sd{3}")); // 輸出為 trueNPC:"非常棒,我的勇士!希望這三個基本規則還不至于讓你記昏了頭。不過請放心,沒有其他字母需要記憶了,只有這三個而已。"
第五回 更進一步
NPC:"記住上面三個規則之后,你還可以順帶獲得幾個新的規則。因為正則國度規定:將字母換成大寫,就表示相反的意思。用 d 你可以匹配一個數字,D 則表示匹配一個非數字。"
System.out.println("a".matches("d")); // 輸出為 false System.out.println("1".matches("d")); // 輸出為 trueSystem.out.println("a".matches("D")); // 輸出為 true System.out.println("1".matches("D")); // 輸出為 false你:"哈,設計者真是太機智了,大大減少了我這種新手的學習成本。"
NPC:"是的,這非常好記。類似地,W 可以匹配 w 不能匹配的字符,S 可以匹配 s 不能匹配的字符。"
第六回 漸入佳境
NPC:"有時候,我們對某些位置的字符沒有要求,僅需要占個位置即可。這時候我們就可以用 . 字符。"
System.out.println("a0b".matches("a.b")); // 輸出為 true System.out.println("a_b".matches("a.b")); // 輸出為 true System.out.println("a b".matches("a.b")); // 輸出為 true你:"那是不是也可以理解為:.可以匹配任意字符。"
NPC:"是的,可以這么理解。還記得之前說的{n}表示匹配n次嗎?有時候,我們對匹配的次數沒有要求,匹配任意次均可,這時,我們就可以用*字符。"
System.out.println("1".matches("d*")); // 輸出為 true System.out.println("123".matches("d*")); // 輸出為 true System.out.println("".matches("d*")); // 輸出為 true你:"我有疑問,為什么第三個表達式也會輸出 true 呢?明明沒有出現數字啊?"
NPC:"那意味著出現了 0 次,* 是指 可以匹配任意次,包括 0 次。也就是說,* 等價于 {0,}"
你:"我感覺比較常見的需求應該是某個字符至少出現一次吧?"
NPC:"那就可以用 + 匹配,+ 表示 至少匹配一次。它等價于 {1,}"
System.out.println("1".matches("d+")); // 輸出為 true System.out.println("123".matches("d+")); // 輸出為 true System.out.println("".matches("d+")); // 輸出為 false你:"哈哈,看來設計者也發現了這個需求更常用。平時+號比*號用得多吧"!你感覺自己猜到了語法設計者的想法,洋洋得意地對 NPC 說道。
"這倒沒人統計過",NPC 白了你一眼,"在我們正則的國度,常常是一個場景一個正則,不存在誰比誰更常用的對比,按照實際場景使用就行了。"
NPC:"還有一種場景,如果某個字符要么匹配 0 次,要么匹配 1 次,我們就可以用?匹配。它等價于{0,1}"
System.out.println("".matches("d?")); // 輸出為 true System.out.println("1".matches("d?")); // 輸出為 true System.out.println("123".matches("d?")); // 輸出為 false你:".匹配任意字符;*匹配任意次,包括 0 次;+號匹配至少 1 次,?匹配 0 次或 1 次。我記住了!"
第七回 心浮氣躁
一下子掌握了這么多的正則匹配規則的你有點飄飄然,于是你對 NPC 說道:"我感覺我已經掌握了夠多的匹配規則,足以應付所有的字符串匹配場景了!"
NPC:"是的,你已經掌握了足夠多的規則,勇士。可先別得意得太早,我再考考你吧。看看匹配電話號碼的程序,如果我們規定電話號碼不能以 0 開頭,應該怎么寫正則表達式呢?"
"不能以0開頭,那就不能用d{11}了,這......",你抓耳撓腮,為難起來。
這時,調皮的 NPC 學著你剛才的樣子,說道:"我已經掌握了足夠多的匹配規則,足以應付所有的字符串匹配場景了!"
你:"呃,還差一點......快別取笑我了,快告訴我這個要用什么新的規則吧!"
"年輕人啊,總是心浮氣躁",NPC 搖了搖頭,"這樣的場景需要用[]來匹配,[]用于匹配指定范圍內的字符,比如[123456789]可以匹配 1~9。"
System.out.println("1".matches("[1-9a-gU-Z]")); // 輸出為 true System.out.println("b".matches("[1-9a-gU-Z]")); // 輸出為 true System.out.println("X".matches("[1-9a-gU-Z]")); // 輸出為 true System.out.println("A".matches("[1-9a-gU-Z]")); // 輸出為 false你:"這可真是太方便了!如果是 0~1,8~9 可以這樣組合嗎?"
NPC:"那樣的話,你寫 [0189] 不是更簡潔嗎?"
你:"我想學習(裝 X)。"
NPC:"那當然也是可以的,[0-18-9] 正是你想要的。由于正則一次只匹配一個字符,所以這樣寫并不會有歧義,也就是說計算機不會把這種寫法誤解成要匹配 0~18 之類的。"
System.out.println("1".matches("[0-18-9]")); // 輸出為 true System.out.println("5".matches("[0-18-9]")); // 輸出為 falseNPC:"還有一種寫法可以實現這一點,那就是用或運算符,正則的或運算符是|,[0189]也可以寫作0|1|8|9。"
System.out.println("1".matches("0|1|8|9")); // 輸出為 true System.out.println("5".matches("0|1|8|9")); // 輸出為 false你:"所以說范圍就是或的簡寫,對嗎?"
NPC:"不對,或可以實現更多的功能,它并不局限于單個字符。"
System.out.println("abc".matches("abc|ABC")); // 輸出為 true System.out.println("ABC".matches("abc|ABC")); // 輸出為 true System.out.println("123".matches("abc|ABC")); // 輸出為 false你:"如果我想排除某些字符呢?比如這個位置不能是[123]。我記得你之前說正則王國以大寫表示取反,[]要怎么大寫呢?"
NPC:"[]可沒有大寫之說,[]取反的方式是:[^],比如不能是[123]的表示方法為[^123]或者[^1-3]"
你:"原來如此,我懂了。現在還有什么規則我沒有學到的嗎?"
NPC:"新手教程到這里就結束了,這已經足夠你應付許多應用場景了。但我這還有兩本高手秘籍,你想不想學呢?"
你:"高手秘籍!聽著都讓人激動啊,快講講!"
第八回 探囊取物
NPC:"這第一本秘籍的名字叫 探囊取物。考慮一個實際需求,有許許多多以下格式的字符串,你需要用正則表達式匹配出其姓名和年齡。
- Name:Aurora Age:18
- 其中還夾雜著一些無關緊要的數據
- Name:Bob Age:20
- 錯誤的數據有著各種各樣錯誤的格式
- Name:Cassin Age:22
- ..."
你:"沒問題,這已經難不倒我了。讓我想想......觀察字符串的規則,只需要用 Name:w+s*Age:d{1,3} 就能匹配了。"
System.out.println("Name:Aurora Age:18".matches("Name:w+s*Age:d{1,3}")); // 輸出為 true System.out.println("其中還夾雜著一些無關緊要的數據".matches("Name:w+s*Age:d{1,3}")); // 輸出為 false System.out.println("Name:Bob Age:20".matches("Name:w+s*Age:d{1,3}")); // 輸出為 true System.out.println("錯誤的數據有著各種各樣錯誤的格式".matches("Name:w+s*Age:d{1,3}")); // 輸出為 false System.out.println("Name:Cassin Age:22".matches("Name:w+s*Age:d{1,3}")); // 輸出為 trueNPC:"很好!一般來說,下一步你要做的就是取出這些表達式中的姓名和年齡,以便把它們存到數據庫中。"
你:"那我可以用 indexOf 和 subString 函數來取這些值。 "
NPC:"的確可行,但你現在不需要那個蠢辦法了,我的勇士。你已經掌握了正則的力量,在我們正則國度有更簡潔的取值方式。"
Pattern pattern = Pattern.compile("Name:(w+)s*Age:(d{1,3})"); Matcher matcher = pattern.matcher("Name:Aurora Age:18"); if(matcher.matches()) {String group1 = matcher.group(1);String group2 = matcher.group(2);System.out.println(group1); // 輸出為 AuroraSystem.out.println(group2); // 輸出為 18 }NPC:"看吧,只要用()將需要取值的地方括起來,傳給 Pattern 對象,再用 Pattern 對象匹配后獲得的 Matcher 對象來取值就行了。每個匹配的值將會按照順序保存在 Matcher 對象的 group 中。"
NPC:"你可以看到我用()把w+和d{1,3}分別括起來了,判斷 Pattern 對象與字符串是否匹配的方法是Matcher.matches(),如果匹配成功,這個函數將返回 true,如果匹配失敗,則返回 false。"
你:"這里是不是寫錯了,為什么 group 是從下標 1 開始取值的,計算機不都從 0 開始數嗎?"
NPC:"并沒有寫錯,這是因為 group(0) 被用來保存整個匹配的字符串了。"
System.out.println(matcher.group(0)); // 輸出為 Name:Aurora Age:18你:"原來是這樣,分組可真是太方便了。但我們之前都是用的String.matches方法來匹配的正則表達式,這里用的 Pattern 又是什么呢?"
NPC:"想知道這個問題的答案的話,我們不妨來看一下String.matches方法的源碼。"
public boolean matches(String regex) {return Pattern.matches(regex, this); }"源碼中調用了Pattern.matches方法,我們再跟進去。"
public static boolean matches(String regex, CharSequence input) {Pattern p = Pattern.compile(regex);Matcher m = p.matcher(input);return m.matches(); }你:"啊,我明白了!原來 Pattern 并不是什么新鮮東西,String.matches內部就是調用的 Pattern,兩種寫法的原理是一模一樣的!"
NPC:"沒錯,并且閱讀源碼之后,你可以發現,每次調用String.matches函數,都會新建出一個 Pattern 對象。所以如果要用同一個正則表達式多次匹配字符串的話,最佳的做法不是直接調用String.matches方法,而應該先用正則表達式新建一個 Pattern 對象,然后反復使用,以提高程序運行效率。"
// 錯誤的做法,每次都會新建一個 Pattern,效率低 boolean result1 = "Name:Aurora Age:18".matches("Name:(w+)s*Age: (d{1,3})"); boolean result2 = "Name:Bob Age:20".matches("Name:(w+)s*Age: (d{1,3})"); boolean result3 = "Name:Cassin Age:22".matches("Name:(w+)s*Age: (d{1,3})");// 正確的做法,復用同一個 Pattern,效率高 Pattern pattern = Pattern.compile("Name:(w+)s*Age:(d{1,3})"); boolean result4 = pattern.matcher("Name:Aurora Age:18").matches(); boolean result5 = pattern.matcher("Name:Bob Age:20").matches(); boolean result6 = pattern.matcher("Name:Cassin Age:22").matches();第九回 移花接木
NPC:"我這第二本秘籍名為 移花接木。再考慮一個實際場景:你有一個讓用戶輸入標簽的輸入框,用戶可以輸入多個標簽。可是你并沒有提示用戶,標簽之前用什么間隔符號隔開。"
你:"你還別說,我之前真遇到過這個問題。結果用戶的輸入五花八門,有用逗號的,有用分號的,有用空格的,還有用制表符的......"
- 二分,回溯,遞歸,分治
- 搜索;查找;旋轉;遍歷
- 數論 圖論 邏輯 概率
NPC:"那你是怎么解決的呢?"
你:"用 String.split 函數唄,這個函數我已經用得很熟練了。將各種分隔符號依次傳入嘗試,最后總算是解決了。"
public static String[] splitTabs(String tabs) {if(tabs.split(",").length == 4) return tabs.split(",");if(tabs.split(";").length == 4) return tabs.split(";");if(tabs.split(" ").length == 4) return tabs.split(" ");return new String[0]; }public static void main(final String[] args){System.out.println(Arrays.toString(splitTabs("二分,回溯,遞歸,分治")));System.out.println(Arrays.toString(splitTabs("搜索;查找;旋轉;遍歷")));System.out.println(Arrays.toString(splitTabs("數論 圖論 邏輯 概率"))); }輸出為:
[二分, 回溯, 遞歸, 分治] [搜索, 查找, 旋轉, 遍歷] [數論, 圖論, 邏輯, 概率]這時,你看到 NPC 露出了心痛的表情:"暴殄天物啊!你這種行為就好比拿著精心打磨的鉆石當電鉆頭,這樣的代碼在我們正則王國是會遭人唾罵的。"
你:"String.split 函數不就是用來分割字符串的嗎?"
NPC:"當然是,但 split 函數可不是你這樣用的,不知你是否看過 split 函數的源碼,這個函數傳入的參數實際上是一個正則表達式。"
你:"啊?但我之前沒寫過正則表達式,分割出來也沒出錯啊!"
NPC:"當然,你忘了我最開始給你講的了嗎?你直接使用字符串,在正則王國屬于精確匹配,只能匹配你寫死的那個字符串。"
你:"原來如此。那么我應該怎么做呢?"
NPC:"當然是用正則表達式模糊匹配,只要能匹配成功,就以其分割。"
System.out.println(Arrays.toString("二分,回溯,遞歸,分治".split("[,;s] +"))); System.out.println(Arrays.toString("搜索;查找;旋轉;遍歷".split("[,;s] +"))); System.out.println(Arrays.toString("數論 圖論 邏輯 概率".split("[,;s] +")));輸出為:
[二分, 回溯, 遞歸, 分治] [搜索, 查找, 旋轉, 遍歷] [數論, 圖論, 邏輯, 概率]你:"原來 split 函數這么強大,我以后不會犯這種錯誤了!"
NPC:"字符串中,可不止這一個函數是傳入的正則表達式,你還記得替換所有匹配字符串用的什么函數嗎?"
你:"用的是 replaceAll 函數,這個函數不會也是傳的正則表達式吧!"
NPC:"正是這樣,所以我們可以用正則表達式模糊匹配,將符合規則的字符串全部替換掉。比如就現在這個例子,我們可以把用戶輸入的所有數據統一規范為使用 ; 分隔,那我們就可以這樣寫。"
System.out.println("二分,回溯,遞歸,分治".replaceAll("[,;s]+", ";")); System.out.println("搜索;查找;旋轉;遍歷".replaceAll("[,;s]+", ";")); System.out.println("數論 圖論 邏輯 概率".replaceAll("[,;s]+", ";"));輸出為:
二分;回溯;遞歸;分治 搜索;查找;旋轉;遍歷 數論;圖論;邏輯;概率你:"果然是移花接木,模糊匹配比精確匹配效率高多了!"
NPC:"還不止這一點,在 replaceAll 的第二個參數中,我們可以通過$1,$2,...來反向引用匹配到的子串。只要將需要引用的部分用()括起來就可以了。"
System.out.println("二分,回溯,遞歸,分治".replaceAll("([,;s]+)", "---$1---")); System.out.println("搜索;查找;旋轉;遍歷".replaceAll("([,;s]+)", "---$1---")); System.out.println("數論 圖論 邏輯 概率".replaceAll("([,;s]+)", "---$1---"));輸出為:
二分---,---回溯---,---遞歸---,---分治 搜索---;---查找---;---旋轉---;---遍歷 數論--- ---圖論--- ---邏輯--- ---概率你:"哈,有時候我們不需要替換,只需要將正則匹配出來的部分添加一些前綴或后綴,就可以用這種方式!"
NPC:"完全正確。"
第十回 驀然回首
NPC:"恭喜你學完了所有的正則教程,現在你知道正則表達式是什么了吧。"
你:"沒錯,以前總感覺正則表達式晦澀難懂,每次用到時就去網上搜索答案,現在看來也不過如此。"
NPC:"說 不過如此 倒是有些托大了,雖然我給你介紹了正則表達式的基本規則,但正則表達式里面還有不少的學問可以去挖掘的。每種技術都有一個熟能生巧的過程。"
你:"什么?還有學問?我感覺我已經學完了啊!還有什么學問,一并給我講了吧!"
NPC:"那你看這樣一道題:給你一些字符串,統計其末尾 e 的個數:
- LeetCode
- LeetCodeeee
- LeetCodeee"
你:"看起來并不難,用(w+)(e*)匹配,再取 group(2) 判斷即可。"
Pattern pattern = Pattern.compile("(w+)(e*)"); Matcher matcher = pattern.matcher("LeetCode"); if (matcher.matches()) {String group1 = matcher.group(1);String group2 = matcher.group(2);System.out.println("group1 = " + group1 + ", length = " + group1.length());System.out.println("group2 = " + group2 + ", length = " + group2.length()); }NPC:"你運行一下試試看。"
輸出如下:
group1 = LeetCode, length = 8 group2 = , length = 0你:"怎么會這樣?我期望的結果是 group1 等于 LeetCod,group2 等于 e 才對啊!"
NPC:"這是因為 e 仍然屬于 w 能匹配的范疇,正則表達式默認會盡可能多地向后匹配,我們王國將其稱之為 貪婪匹配。"
你:"貪婪匹配,聽起來和貪心算法有異曲同工之妙。"
NPC:"沒錯,貪婪匹配和貪心算法原理是一致的。與之對應的匹配方式叫做非貪婪匹配,非貪婪匹配會在能匹配目標字符串的前提下,盡可能少的向后匹配。"
你:"那么,我要怎樣指定匹配方式為非貪婪匹配呢?"
NPC:"也很簡單,在需要非貪婪匹配的正則表達式后面加個 ? 即可表示非貪婪匹配。"
Pattern pattern = Pattern.compile("(w+?)(e*)"); Matcher matcher = pattern.matcher("LeetCode"); if (matcher.matches()) {String group1 = matcher.group(1);String group2 = matcher.group(2);System.out.println("group1 = " + group1 + ", length = " + group1.length());System.out.println("group2 = " + group2 + ", length = " + group2.length()); }運行程序,輸出如下:
group1 = LeetCod, length = 7 group2 = e, length = 1你:"這里也用的是?,我記得之前?表示的是匹配 0 次或者 1 次,兩個符號不會混淆嗎?"
NPC:"不會混淆的,你仔細想一想就能明白了,如果只有一個字符,那就不存在貪婪不貪婪的問題,如果匹配多次,那么表示非貪婪匹配的?前面必有一個標志匹配次數的符號。所以不會出現混淆。"
你:"最后一個問題,為什么這里沒有匹配成 group1 等于 L,group2 等于 ee...... 哦我明白了,如果這樣匹配的話,字符串LeetCode就無法和正則表達式匹配起來。怪不得非貪婪匹配的定義是在能匹配目標字符串的前提下,盡可能少的向后匹配。"
NPC:"就是這個原理,看來你是真的完全明白了。"
第十一回 最終考驗
NPC:"天下沒有不散的宴席,是時候說再見了。雖然我能教你的,或是說想與你探討的,還不止這些內容,但授人以魚不如授人以漁,以后遇到正則相關的問題,還是要靠你自己動腦思考。"
你:"這么快就要告別了嗎?不知道為什么,竟然還有點舍不得......"
NPC:"我最后再出一道題考考你,你就可以從正則王國順利畢業了。來看下你的題目吧:我們王國有一個人口吃,請你幫忙矯正他。他今天說:肚...子。。好餓........,....早知道.....當.....初...。。。多.....刷.....點。。。力.....扣了.........!"
你:"ez,只需要用 str.replaceAll(__, __) 就可以解決了!"
互動話題:
嘿,說你呢!在留言區寫下你的答案吧!
本文作者:Alpinist Wang
聲明:本文歸 “力扣” 版權所有,如需轉載請聯系。
總結
以上是生活随笔為你收集整理的java正则匹配英文句号_「正则表达式」王国奇遇记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ip 地址 192.168.1.255
- 下一篇: 文件自定义变量_awk 内置变量与自定义