女人夜夜春高潮爽A∨片传媒_国产精品VIDEOS麻豆_在线精品亚洲一区二区三区_亚洲熟妇无码av

編程代碼
新聞詳情

C++與正則表達式入門(一)

發布時間:2020-10-16 11:36:45 最后(hou)更新:2020-11-23 14:32:15 瀏覽次數:3024

什么是正則表達式?

正(zheng)則(ze)表(biao)達式是一組由(you)字母和符(fu)號組成的(de)特(te)殊文(wen)本, 當(dang)你(ni)想要判斷許多字符(fu)串是否符(fu)合某個(ge)特(te)定格式;當(dang)你(ni)想在一大(da)段文(wen)本中(zhong)查找出所(suo)有的(de)日期和時(shi)間;當(dang)你(ni)想要修改大(da)量日志(zhi)中(zhong)所(suo)有的(de)時(shi)間格式,在這些情況(kuang)下,正(zheng)則(ze)表(biao)達式都能幫(bang)上(shang)忙。

簡單來(lai)說(shuo),正(zheng)則(ze)表(biao)達式描述了一(yi)系(xi)列規(gui)(gui)則(ze),通過這些規(gui)(gui)則(ze),可(ke)以在字符串中(zhong)找(zhao)到(dao)相關的內容,規(gui)(gui)則(ze)使得(de)搜索的能力更(geng)加強大。匹配的過程由正(zheng)則(ze)表(biao)達式引(yin)(yin)擎(qing)完成(cheng)。開發者通常不需要關心(xin)正(zheng)則(ze)表(biao)達式引(yin)(yin)擎(qing)的實(shi)現(xian)細節,直接使用(yong)其(qi)提供(gong)的能力即可(ke)。

大家可以先想(xiang)象你(ni)正在寫一個(ge)應用(yong), 然后(hou)你(ni)想(xiang)設定一個(ge)用(yong)戶(hu)命名的規則(ze), 讓用(yong)戶(hu)名包含字(zi)(zi)符,數(shu)字(zi)(zi),下(xia)劃(hua)線和連字(zi)(zi)符,以及限(xian)制(zhi)字(zi)(zi)符的個(ge)數(shu),好讓名字(zi)(zi)看(kan)起來沒那么丑. 我(wo)們使用(yong)以下(xia)正則(ze)表達式(shi)來驗證一個(ge)用(yong)戶(hu)名:

以上的正則表達式可以接受 john_doe , john12_as . 但不匹配 Jo , 因(yin)為它包含了大寫的字母(mu)而且太短了.

本文將以C++語言為例,介紹其中的正則(ze)表達式(shi)相關知識。



C++中正則表達式的API基本上都位于頭文件中。

部分代碼為了簡化(hua)書寫,都已經默認做(zuo)了以(yi)下操作:


入門示例

為了使大家有一(yi)(yi)個(ge)直觀(guan)的(de)感(gan)(gan)受(shou),文(wen)章的(de)開頭先通過一(yi)(yi)些入門示例給大家一(yi)(yi)個(ge)直觀(guan)的(de)感(gan)(gan)受(shou)。在(zai)這個(ge)基礎之上,再詳細講解(jie)其中的(de)細節(jie)。

使用正則表達式的大致流程如下:首先你有一段需要處理的文本。這可能是一個字符串對象,也可能是一個文本文件,或者是一大堆日志。接下來你會有特定的目標,例如:找出文本中所有的時間和日期。這個時候你就需要根據可能的格式寫出具體的正則表達式,例如,日期的格式是:2020-01-01,那么你的正則表達式可能是這樣:。(你(ni)現在(zai)不必糾結與這個正(zheng)則表(biao)達式是什么意思,因為這是本文接下來要講解的內容。)

有了正則表(biao)(biao)達(da)(da)式(shi)之后(hou),你(ni)需要將你(ni)的(de)文本(ben)和正則表(biao)(biao)達(da)(da)式(shi)交給正則表(biao)(biao)達(da)(da)式(shi)引擎(qing) – 由C++語言(或者其(qi)他語言)提供。引擎(qing)會在文本(ben)中搜索到匹配的(de)結果。這個結果的(de)格式(shi)可能是包含了多個組,例如:你(ni)可能需要分離(li)出年份(fen)和月(yue)份(fen)。有了引擎(qing)返(fan)回的(de)結果之后(hou),你(ni)就可以進一(yi)步處理了。

使用(yong)正則表達式的流(liu)程(cheng)大體都是一致的,下(xia)面是最常見(其他形式大多為其變種)的三種使用(yong)方式。

匹配

匹配是判斷(duan)給定(ding)的字符串是否(fou)符合某個正(zheng)則表(biao)達式。例如(ru):你想(xiang)判斷(duan)當前文本是否(fou)全(quan)部由數字構(gou)成。

下(xia)面是一段(duan)代碼(ma)示例:


在這段代碼中:

  1. 這是一個包含了數字和字母的字符串
  2. 這是一個只包含了數字的字符串
  3. 這是我們的正則表達式,它表示:有多個數字cpp
  4. 通過判斷第一個字符串是否匹配,這里將返回false
  5. 通過判斷第二個字符串是否匹配,這里將返回true

這段代碼輸出如下:


搜索

還有一(yi)些(xie)時候,我們(men)要判(pan)斷的并非是文(wen)本的全體是否匹配。而是在一(yi)大段文(wen)本中搜索匹配的目標。

下面(mian)是一段代碼示例,這段示例演示了在(zai)一個字符串中查找數(shu)字:

  1. 這是一個包含了數字和字母的字符串
  2. 和前面一樣的正則表達式
  3. 通過來保存匹配的結果。除了,還有也很常用。前者是以的形式返回結果,后者是以的形式返回結果。
  4. 通過函數搜索結果
  5. 打印出匹配的結果

這段代碼輸出如下:

替換

最后,使(shi)用正則(ze)表達(da)式的還有(you)一個(ge)常(chang)見功能是(shi)文本替換(huan)。很多的編輯(ji)器都有(you)這樣的功能。

例如,下圖是我(wo)的(de)(de)Visual Studio編譯器,在搜索(suo)替(ti)(ti)換文本(ben)的(de)(de)時候,可以使用正則(ze)表(biao)(biao)達(da)式(shi),這(zhe)時搜索(suo)的(de)(de)能力就更加強(qiang)大了(le)。“Find:”部分可以通過正則(ze)表(biao)(biao)達(da)式(shi)來描述待替(ti)(ti)換的(de)(de)字(zi)符串(chuan),“Replace:”部分填寫(xie)替(ti)(ti)換的(de)(de)字(zi)符串(chuan)。

下面(mian)是在C++中(zhong)使用正則(ze)表達式(shi)完(wan)成字符串替換的(de)代碼(ma)示例:

  1. 仍然是前面這個字符串
  2. 仍然是同樣的正則表達式
  3. 通過完成替換
  4. 通過輸出結果

最終(zhong)輸出的字符串如下:

通過上面的三個示例我們看到,三個函數(shu)是正(zheng)則表達式(shi)的核心,它們會運行正(zheng)則表達式(shi)引擎完成匹配,查(cha)找和替(ti)換任(ren)務。

正則表達式文法

文法

C++中內置(zhi)了(le)多種正(zheng)則表達式(shi)文法,在創建(jian)正(zheng)則表達式(shi)的時候可以通過參數來選擇。


不同的文法在表達上有一些不同,如果你原先已經很熟悉或者文法的正則表達式,你可以直接使用它們。對于其他人來說,我們直接使用默認的ECMAScript文法即可(的正則表達式也是使用ECMAScript文法)。

C++ 中的 ECMAScript 正則表達式文法是 ,你可以點擊鏈(lian)接查看詳細內容。

下文中,將會 引用 :關于的解釋

Raw string literal (原始字符串)

在代碼(ma)中寫字符串(chuan)有(you)時(shi)候是比較麻煩的,因為很多字符需要(yao)通過反斜(xie)杠(gang)轉義(yi)。當有(you)多個反斜(xie)杠(gang)連在一起時(shi),就(jiu)很容易寫錯(cuo)或者理解錯(cuo)了(le)。

當通過字符串來寫正則表達式時,這個問題就更嚴重了。因為正則表達式本身也有一些字符需要轉義。例如,對于這樣一個字符串  大部分人(ren)恐怕很難一(yi)眼看出(chu)其含義了。

在正則表達式很復雜的時候,推薦大家使用來表達。這種表達式是告訴編譯器:這里的內容是純字符串,因此不再需要增加反斜杠來轉(zhuan)義特殊字符。

Raw string literal 的格式如下:

這其中:

  • delimiter是可選的分隔符,通常不用寫
  • raw_characters是具體的字符串

也就是說,中的是你(ni)需要的字符串本身(shen)。

下(xia)面是一個代(dai)碼示(shi)例:

它將輸出:

可以看到(dao),這里的雙引號和反(fan)斜杠不會被解(jie)(jie)釋成轉(zhuan)義字符,而是當成字符串內容本身,因此會原樣(yang)輸出。這樣(yang)就減少(shao)了轉(zhuan)義字符的復雜度,于是更容易理(li)解(jie)(jie)了。

特殊字符

正則表(biao)達式(shi)本身(shen)定義(yi)了一(yi)些特(te)殊(shu)的字符(fu),這些字符(fu)有著特(te)殊(shu)的含義(yi)。它們如下表(biao)所示。

這些(xie)字符并不少(shao),剛開始接觸(chu)可能記不住(zhu),但(dan)隨(sui)著下文的(de)講解,相(xiang)信(xin)你會逐漸熟悉它們(men)。

字符類

字(zi)符(fu)類,顧名(ming)思義:是對字(zi)符(fu)的分類。

例如:1234567890這些都(dou)屬于數字字符類。除(chu)此之外(wai),還有其他的分類,它們如下表所示(shi):

這里我們可以看到:

  • 字符類通過作為標識,因此這兩個字符是正則表達式的中的特殊字符。如果是想使用這兩個字符本身,需要對它們進行轉義。
  • 內部,通過來描述字符類的名稱。
  • 中可以通過表示否定,即:字符類的反面。
  • 字母,數字和空白字符由于這些字符類非常常用,因此它們有簡寫的方法。簡寫使得正則表達式更加簡潔,但表達的含義是一樣的。

接下(xia)來我(wo)們看一個(ge)代(dai)碼示(shi)例:

這段代碼稍(shao)微有些長,但還是比較好理解的。

該程序的輸出如下:

請仔細看一下這個輸出(chu),并確(que)認與你的(de)(de)認知(zhi)是(shi)否(fou)一致。這里的(de)(de)有(you)些字(zi)符(fu)(fu)類包含(han)了(le)換行符(fu)(fu),因此在輸出(chu)的(de)(de)結果(guo)中(zhong)也是(shi)換行的(de)(de)。

重復

上面的(de)示例中,我們(men)一次只(zhi)匹配了一個字符。這(zhe)樣(yang)做效率(lv)是(shi)很(hen)低的(de)。

在很(hen)多(duo)時候,我(wo)們(men)當然是想一(yi)次性匹配出一(yi)個(ge)完(wan)整的字符(fu)(fu)串。例(li)如(ru):一(yi)個(ge)手機號碼。這種情況(kuang)下,其實是多(duo)個(ge)數字字符(fu)(fu)的重復。

下面(mian)就是在正則(ze)表達式中描述(shu)重(zhong)復的(de)(de)方式。它們通常(chang)跟(gen)在字符(fu)類的(de)(de)后面(mian),描述(shu)該字符(fu)出(chu)現多次。

知道重復(fu)的方法之后,正(zheng)則表達式的查(cha)找(zhao)能(neng)力就更強大了。看一下下面這個代(dai)碼示例:

在這段代碼中:

  1. 這里定義了一個函數,它接受一個正則表達式和字符串。
  2. match_result用來存儲查找的結果。
  3. 設置輸出格式,為了讓輸出對齊。
  4. 通過regex_search在字符串中查找匹配字符。
  5. 輸出匹配的結果。
  6. 待匹配的字符串。
  7. [[:alnum:]]{5}是指:字符或者數字出現5次。
  8. \\w{5,}是指:字母,數字或者下劃線出現5次或更多次。
  9. R"(\W{3,5})"是指:非字母,數字或者下劃線出現3次到5次。
  10. [[:digit:]]*是指:數字出現任意多次。
  11. .+是指:任意字符出現至少1次。
  12. [[:lower:]]?是指:小寫字母出現0次或者1次。

該程序輸出如下:

在線客服
客服電(dian)話
  • 0755-23712116
  • 13310869691