正則表達式的匹配規則「正則匹配任意字符和空格」

正則表達式的組成元素?

我們在編碼過程中無論前端或者後端或多或少會遇到正則表達式,她雖然不是必須的,但是錦上添花是一定的,所以我們有必要去掌握它的規則,讀懂他,了解他的語義,直至自己按規則寫出自己業務邏輯的正則表達式,比如我們在修改維護人家的代碼或者賞析源代碼看到類似的字符串

(<(w*)([^>]*)>)|((?<=>).*?(?=<))

如果我們不了解語義規則,是不是心裏慌得一P,心裏萬馬奔騰,啥玩意東西?我在哪裡,我是誰,我不活了?

正則表達式教程 #2 如何讀懂一個正則表達式?

還是有必要花點時間來學習下,如果各位同學觀賞了上面的表達式產生和作者當初一樣的情緒,恭喜你,兩種選擇,

一:自己面壁去

二:點個關注,給碼字的作者一點小小的鼓勵再拿個小板凳,仔細聽我詳細分解

言歸正傳,我們首先理解正則表達式的第一個基本概念:

元字符(metacharacter)

當一個字符在正則引擎中賦予特殊意義,而不再代表字符本身含義,比如.在ASCII碼中為46,在正則表達式語義環境中代表除開換行結束符之外任意字符,這句話究竟什麼含義也?換句話說就是比如孫大聖的七十二變,根據具體的場景,他可以變成一隻小小鳥,也可以變成一個漂亮小姐姐,或者其他任何東西,從引擎解析的角度可以假裝是我們要找的那個東西,到達我們想要搜索結果,和我們sql裏面的%通配符一樣的語義

拆分正則表達式最小元字符組

文本字符:

代表字符的本身含義,比如字符a代表ASCII 碼是97,他可以匹配你搜索字符串任何位置的a字符,相當於精確匹配。

匹配單個字符元字符:

從表達式構建來說,一次匹配模式可以由一個元字符構成,也可以由多個元字符構造一組元字符完成一次匹配,那麼讀懂正則表達式就必須要求你有一雙慧眼,可以把正則表達式拆分成一個(組)一個(組)的一次匹配模式,畫重點:

  • [A-F0-9] 字符集合區間中任意一個字符都可以匹配,匹配一次消費一個搜索字符串字符
  • d 0到9任意一個數字
  • D 匹配非數字
  • [A-Za-z0-9] 匹配任意大小寫字母、數字
  • w 和上面相同,匹配任意大小寫字母、數字,因為正則語言規則最先是linux使用的,這種使用頻率過高,語法太繁瑣了,作者在引擎中又自定義了一個簡單的元字符來表述該語義,如果我們自己實現的正則引擎,你可以隨意發揮,用某個簡單的符號(元字符)代表某一類語義.
  • 一樣的道理,其他還有很多,看你用具體哪個語法那種正則引擎,大致差不多,剩下的就僅僅是使用熟悉的過程而且 So easy!

轉義序列元字符 :

當我們想用元字符本身的語義去匹配我們的搜索字符串的時候,用來讓正則引擎定義的元字符回歸本源,比如我們想匹配IP地址:(d{1,3}.){3}d{1,3} 其中當正則引擎解析到.僅僅能匹配字符.,而不是匹配除開換行結束符之外任意字符。

位置匹配:

零寬斷言)只匹配位置,不匹配字符,不consume字符,比如

  • ^ 匹配字符串的邊界,行首
  • $ 匹配字符串的邊界,行尾
  • b一個單詞的邊界
//eg:
//功能:清理空白行
final String regex = "^s*?n";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
String input = "
正則表達式教程 #2 如何讀懂一個正則表達式?

替換清理如圖文本空行,該表達式可以拆分成三組元字符組:

  • regex[0] = ^表示斷言一行的起始位置
  • regex[1] = s*? 表示匹配任意多個字符匹配空白符(等價於[rntfv ])
  • regex[2] = n 表示匹配換行符最後匹配到的結果替換為字符串空,即實現刪除空白行

量詞元字符:

重複匹配,定位前面(文本元字符|字符元字符|分組元字符組)匹配重複的次數

  • ? 匹配字符或者字符集合出現0次或者1次
  • * 匹配字符或者字符集合出現0次或者n次
  • + 匹配字符或者字符集合出現1次或者N次
  • {m} 匹配模式必須出現m次
  • {m,} 匹配模式最少出現m次,最多無窮N次
  • {m,n} 匹配模式最少m次,最多n次

分組捕獲元字符( ):

該分組類所有元字符組匹配看着一個完整分組作為一次匹配,而且查找最近的配對閉合括弧作為一個完整的子模式,注意該分組裏面也許有N多個子分組,一定要追溯到所有的子分組閉合之後,分組是正則表達式一個重要的概念,但是對於我們目前僅僅學習如何拆分一個正則表達式夠了,具體子表達式具體開文詳細講。

條件選擇元字符 或 |:

表示幾個並行的條件,只要其中一個滿足,就匹配成功

String regex1 = "(li|zh)ang";
// regex1:既能匹配liang也可以匹配zhang
String regex2 = "[li|zh]ang";
// 注意和範圍單個字符匹配的不同,regex2這樣寫可以匹配lang iang |ang zang hang 這種組合

實戰:根據上面的準備,我們來拆分開篇正則表達式: (<(w*)([^>]*)>)|((?<=>).*?(?=<))

拆分過程:

//第一次拆分:
var group1 = regex[0] = (<(w*)([^>]*)>); (這個我不認識(。•ˇ‸ˇ•。))
var group2 = regex[1] = | ;(這個我認識,分支條件嘛)
var group3 = regex[2] = ((?<=>).*?(?=<));(這個我不認識(。•ˇ‸ˇ•。))
//第二次拆分:繼續拆分group1元字符組:
var group1_child_1 = group1[0] = < (這個我認識哦,原來你是匹配字符<)
var group1_child_2 = group1[1] = (w*) (原來你是配置任意大小寫字母、數字,想想,哦原來作者這裡是匹配html元素標籤啊,比如div、img)
var group1_child_3 = group1[2] = ([^>]*)(匹配直到出現>前的任意字符)
var group1_child_4 = group1[3] = >(匹配字符>)
組合起來改組就是匹配一個html元素的開始帶屬性的標籤,比如:<div id="header">,MD,原來如此的簡單
....
繼續分解,知道拆分成一個一個有意義的子模式,按規則組織匹配字符,讓後我們就能讀懂該正則表達式的終極奧義。

總結:

關鍵字:零寬斷言 元字符 分組

有了這幾個術語的概念,你可以把一個正則表達式庖丁解牛分成一個一個基礎的元字符,弄明白他的意義,中間有不明白的元字符定義,可以查查資料,那麼恭喜你,正則表達式你花5分鐘就入門了。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/273978.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-17 14:09
下一篇 2024-12-17 14:09

相關推薦

發表回復

登錄後才能評論