精品国产色欧洲激情_中文字幕在线欧美日韩制服在线_欢迎观看网站影片国产在线观看伊_日本高清一本视频_ww亚洲无码免费在线观看_午夜片无码区观看_欧美性爱福利资源_丰满少妇肥唇翘臀ⅩXX_欧美日韩另类久久_国内揄拍国内精品对白86

編程代碼
新聞詳情

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

發(fā)布時(shí)間:2020-10-16 11:36:45 最后更新:2020-11-23 14:32:15 瀏覽次數(shù):2682

什么是正則表達(dá)式?

正則表達(dá)式是一組由字母和符號(hào)組成的特殊文本, 當(dāng)你想要判斷許多字符串是否符合某個(gè)特定格式;當(dāng)你想在一大段文本中查找出所有的日期和時(shí)間;當(dāng)你想要修改大量日志中所有的時(shí)間格式,在這些情況下,正則表達(dá)式都能幫上忙。

簡(jiǎn)單來說,正則表達(dá)式描述了一系列規(guī)則,通過這些規(guī)則,可以在字符串中找到相關(guān)的內(nèi)容,規(guī)則使得搜索的能力更加強(qiáng)大。匹配的過程由正則表達(dá)式引擎完成。開發(fā)者通常不需要關(guān)心正則表達(dá)式引擎的實(shí)現(xiàn)細(xì)節(jié),直接使用其提供的能力即可。

大家可以先想象你正在寫一個(gè)應(yīng)用, 然后你想設(shè)定一個(gè)用戶命名的規(guī)則, 讓用戶名包含字符,數(shù)字,下劃線和連字符,以及限制字符的個(gè)數(shù),好讓名字看起來沒那么丑. 我們使用以下正則表達(dá)式來驗(yàn)證一個(gè)用戶名:

learn-regex

以上的正則表達(dá)式可以接受 john_doe , john12_as . 但不匹配 Jo , 因?yàn)樗舜髮懙淖帜付姨塘?

本文將以C++語言為例,介紹其中的正則表達(dá)式相關(guān)知識(shí)。



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

部分代碼為了簡(jiǎn)化書寫,都已經(jīng)默認(rèn)做了以下操作:


入門示例

為了使大家有一個(gè)直觀的感受,文章的開頭先通過一些入門示例給大家一個(gè)直觀的感受。在這個(gè)基礎(chǔ)之上,再詳細(xì)講解其中的細(xì)節(jié)。

使用正則表達(dá)式的大致流程如下:首先你有一段需要處理的文本。這可能是一個(gè)字符串對(duì)象,也可能是一個(gè)文本文件,或者是一大堆日志。接下來你會(huì)有特定的目標(biāo),例如:找出文本中所有的時(shí)間和日期。這個(gè)時(shí)候你就需要根據(jù)可能的格式寫出具體的正則表達(dá)式,例如,日期的格式是:2020-01-01,那么你的正則表達(dá)式可能是這樣:。(你現(xiàn)在不必糾結(jié)與這個(gè)正則表達(dá)式是什么意思,因?yàn)檫@是本文接下來要講解的內(nèi)容。)

有了正則表達(dá)式之后,你需要將你的文本和正則表達(dá)式交給正則表達(dá)式引擎 – 由C++語言(或者其他語言)提供。引擎會(huì)在文本中搜索到匹配的結(jié)果。這個(gè)結(jié)果的格式可能是包含了多個(gè)組,例如:你可能需要分離出年份和月份。有了引擎返回的結(jié)果之后,你就可以進(jìn)一步處理了。

img

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

匹配

匹配是判斷給定的字符串是否符合某個(gè)正則表達(dá)式。例如:你想判斷當(dāng)前文本是否全部由數(shù)字構(gòu)成。

下面是一段代碼示例:


在這段代碼中:

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

這段代碼輸出如下:


搜索

還有一些時(shí)候,我們要判斷的并非是文本的全體是否匹配。而是在一大段文本中搜索匹配的目標(biāo)。

下面是一段代碼示例,這段示例演示了在一個(gè)字符串中查找數(shù)字:

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

這段代碼輸出如下:

替換

最后,使用正則表達(dá)式的還有一個(gè)常見功能是文本替換。很多的編輯器都有這樣的功能。

例如,下圖是我的Visual Studio編譯器,在搜索替換文本的時(shí)候,可以使用正則表達(dá)式,這時(shí)搜索的能力就更加強(qiáng)大了?!癋ind:”部分可以通過正則表達(dá)式來描述待替換的字符串,“Replace:”部分填寫替換的字符串。

image-20200723135813276

下面是在C++中使用正則表達(dá)式完成字符串替換的代碼示例:

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

最終輸出的字符串如下:

通過上面的三個(gè)示例我們看到,,三個(gè)函數(shù)是正則表達(dá)式的核心,它們會(huì)運(yùn)行正則表達(dá)式引擎完成匹配,查找和替換任務(wù)。

正則表達(dá)式文法

文法

C++中內(nèi)置了多種正則表達(dá)式文法,在創(chuàng)建正則表達(dá)式的時(shí)候可以通過參數(shù)來選擇。


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

C++ 中的 ECMAScript 正則表達(dá)式文法是 ECMA-262 文法,你可以點(diǎn)擊鏈接查看詳細(xì)內(nèi)容。

下文中,將會(huì) 引用 保羅的酒吧:關(guān)于正則表達(dá)式的解釋。

Raw string literal (原始字符串)

在代碼中寫字符串有時(shí)候是比較麻煩的,因?yàn)楹芏嘧址枰ㄟ^反斜杠轉(zhuǎn)義。當(dāng)有多個(gè)反斜杠連在一起時(shí),就很容易寫錯(cuò)或者理解錯(cuò)了。

當(dāng)通過字符串來寫正則表達(dá)式時(shí),這個(gè)問題就更嚴(yán)重了。因?yàn)檎齽t表達(dá)式本身也有一些字符需要轉(zhuǎn)義。例如,對(duì)于這樣一個(gè)字符串  大部分人恐怕很難一眼看出其含義了。

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

Raw string literal 的格式如下:

這其中:

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

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

下面是一個(gè)代碼示例:

它將輸出:

可以看到,這里的雙引號(hào)和反斜杠不會(huì)被解釋成轉(zhuǎn)義字符,而是當(dāng)成字符串內(nèi)容本身,因此會(huì)原樣輸出。這樣就減少了轉(zhuǎn)義字符的復(fù)雜度,于是更容易理解了。

特殊字符

正則表達(dá)式本身定義了一些特殊的字符,這些字符有著特殊的含義。它們?nèi)缦卤硭尽?/p>

這些字符并不少,剛開始接觸可能記不住,但隨著下文的講解,相信你會(huì)逐漸熟悉它們。

字符類

字符類,顧名思義:是對(duì)字符的分類。

例如:1234567890這些都屬于數(shù)字字符類。除此之外,還有其他的分類,它們?nèi)缦卤硭荆?/p>

這里我們可以看到:

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

接下來我們看一個(gè)代碼示例:

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

該程序的輸出如下:

請(qǐng)仔細(xì)看一下這個(gè)輸出,并確認(rèn)與你的認(rèn)知是否一致。這里的有些字符類包含了換行符,因此在輸出的結(jié)果中也是換行的。

重復(fù)

上面的示例中,我們一次只匹配了一個(gè)字符。這樣做效率是很低的。

在很多時(shí)候,我們當(dāng)然是想一次性匹配出一個(gè)完整的字符串。例如:一個(gè)手機(jī)號(hào)碼。這種情況下,其實(shí)是多個(gè)數(shù)字字符的重復(fù)。

下面就是在正則表達(dá)式中描述重復(fù)的方式。它們通常跟在字符類的后面,描述該字符出現(xiàn)多次。

知道重復(fù)的方法之后,正則表達(dá)式的查找能力就更強(qiáng)大了??匆幌孪旅孢@個(gè)代碼示例:

在這段代碼中:

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

該程序輸出如下:

在線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13822267203