C++中使用正則匹配問(wèn)題
C/C++可以用正則表達(dá)式嗎?
答案肯定是可以的,那么,今天一個(gè)簡(jiǎn)單的輸入scanf帶你走進(jìn)正則的世界
#include<stdio.h> int main() { ?? ?printf("input digate:"); ?? ?char str[100]; ?? ?scanf("%[0-9]", str);?? ?//輸入123456abc ?? ?printf("%s", str);?? ??? ?//打印123456 }
在scanf時(shí)輸入任何一串以數(shù)字開(kāi)始的字符,那么str里面只會(huì)保存字符里面的第一串?dāng)?shù)字
input digate:123456abc 123456
先給出一些簡(jiǎn)單的正則
限定符 | 含義 |
---|---|
%[0-9] | 數(shù)字集合 |
%[^0-9] | 非數(shù)字集合 |
%[a-zA-Z] | 字母集合 |
%[^a-zA-Z] | 非字母集合 |
預(yù)熱好了,正題開(kāi)始…
若要判斷一個(gè)輸入的QQ號(hào)是否有效,如何判斷?
判斷步驟:
- 長(zhǎng)度大于5,小于等于11;
- 首位不能為0;
- 是否為純數(shù)字?
C++string處理:
#include<iostream> using namespace std; int main() { string qq = "7466a2063"; if (qq.length() >= 5 && qq.length() <= 11) { // 2. 判斷是否非'0'開(kāi)頭 if (qq[0] != '0') { // 3. 判斷是否為純數(shù)字 for each (char var in qq) { cout << var; if (var < '0' || var > '9') { cout << "不存在" << endl; return 0; } } cout << "存在" << endl; } else { cout << "不存在" << endl; } } else { cout << "不存在" << endl; } return 0; }
雖然功能實(shí)現(xiàn)了但是非常麻煩
正則處理:
#include<iostream> #include<regex> using namespace std; int main() { ?? ?regex qq_reg("[1-9]\\d{4,11}"); ?? ?string qq = "746632063"; ?? ?smatch result; ?? ?bool ret = regex_match(qq, result, qq_reg); ?? ?cout << (ret ? "存在" : "不存在") << endl; ?? ?return 0; }
笑出了聲,一行正則匹配就解決了
是不是很方便呢?那么接下來(lái)便來(lái)看看如何使用「正則表達(dá)式」。
正則程序庫(kù)(regex)
「正則表達(dá)式」就是一套表示規(guī)則的式子,專(zhuān)門(mén)用來(lái)處理各種復(fù)雜的操作。
std::regex是C++用來(lái)表示「正則表達(dá)式」(regular expression)的庫(kù),于C++11加入,它是class std::basic_regex<>針對(duì)char類(lèi)型的一個(gè)特化,還有一個(gè)針對(duì)wchar_t類(lèi)型的特化為std::wregex。
正則文法(regex syntaxes)
std::regex默認(rèn)使用是ECMAScript文法,這種文法比較好用,且威力強(qiáng)大,
常用符號(hào)的意義如下:
符號(hào) | 意義 |
---|---|
^ | 匹配行的開(kāi)頭 |
$ | 匹配行的結(jié)尾 |
. | 匹配任意單個(gè)字符 |
[…] | 匹配[]中的任意一個(gè)字符 |
(…) | 設(shè)定分組 |
\ | 轉(zhuǎn)義字符 |
\d | 匹配數(shù)字[0-9] |
\D | \d 取反 |
\w | 匹配字母[a-z],數(shù)字,下劃線 |
\W | \w 取反 |
\s | 匹配空格 |
\S | \s 取反 |
+ | 前面的元素重復(fù)1次或多次 |
* | 前面的元素重復(fù)任意次 |
? | 前面的元素重復(fù)0次或1次 |
{n} | 前面的元素重復(fù)n次 |
{n,} | 前面的元素重復(fù)至少n次 |
{n,m} | 前面的元素重復(fù)至少n次,至多m次 |
| | 邏輯或 |
上面列出的這些都是非常常用的符號(hào),靠這些便足以解決絕大多數(shù)問(wèn)題了。
匹配(Match)
字符串處理常用的一個(gè)操作是「匹配」,即字符串和規(guī)則恰好對(duì)應(yīng),而用于匹配的函數(shù)為std::regex_match(),它是個(gè)函數(shù)模板
bool regex_match(string s,regex pattern) bool regex_match(string s,smatch result,regex pattern) bool regex_match(s.cbegin()+i,s.cend(),smatch result,regex pattern) ?//從字符串的某個(gè)位置開(kāi)始匹配?
我們直接來(lái)看例子:
#include<iostream> #include<regex> using namespace std; int main() { /*匹配*/ regex pattern("^1[3578]\\d{9}$"); //1開(kāi)頭,后面[3578]中的一個(gè),九個(gè)數(shù)字 string s = "17779637570"; smatch result; bool ismatch = regex_match(s, result, pattern); if (ismatch) { cout << "匹配成功:" << result[0] << endl; } else cout << "匹配失敗" << endl; return 0; }
匹配成功:17779637570
匹配成功并返回匹配到的結(jié)果
搜索(Search)
「搜索」與「匹配」非常相像,其對(duì)應(yīng)的函數(shù)為std::regex_search,也是個(gè)函數(shù)模板,用法和regex_match一樣,不同之處在于「搜索」只要字符串中有目標(biāo)出現(xiàn)就會(huì)返回,而非完全「匹配」。
bool regex_search(string s,regex pattern) bool regex_search(string s,smatch result,regex pattern) bool regex_search(s.cbegin()+i,s.cend(),smatch result,regex pattern) ?//從字符串的某個(gè)位置開(kāi)始匹配?
搜索給定字符串中是否存在與模式匹配的子串,如果存在則返回true。
同樣可以用smatch result記錄結(jié)果,但不同的是result[0]記錄的是整個(gè)字符串中從左往右第一個(gè)匹配模式的子串。
假如有多個(gè)子串符合模式,若想知道result[0]中存儲(chǔ)的是第幾個(gè)子串,可以用result.position()函數(shù),返回?cái)?shù)從0開(kāi)始。
我們直接來(lái)看例子:
#include<iostream> #include<regex> using namespace std; int main() { regex pattern("\\d+"); /*匹配一個(gè)到無(wú)窮個(gè)數(shù)字*/ string s = "51x41+(5-13/2)x3a"; smatch result; string::const_iterator iter_begin = s.cbegin(); string::const_iterator iter_end = s.cend(); while (regex_search(iter_begin, iter_end, result, pattern)) { cout << "查找成功:" << result[0] << endl; cout << "查找結(jié)果子串的在源串中的迭代器位置" << *result[0].first << endl; cout << "查找結(jié)果子串的在源串后面的位置" << *result[0].second << endl; iter_begin = result[0].second; //更新迭代器位置 } return 0; }
查找成功:51
查找結(jié)果子串的在源串中的迭代器位置5
查找結(jié)果子串的在源串后面的位置x
查找成功:41
查找結(jié)果子串的在源串中的迭代器位置4
查找結(jié)果子串的在源串后面的位置+
查找成功:5
查找結(jié)果子串的在源串中的迭代器位置5
查找結(jié)果子串的在源串后面的位置-
查找成功:13
查找結(jié)果子串的在源串中的迭代器位置1
查找結(jié)果子串的在源串后面的位置/
查找成功:2
查找結(jié)果子串的在源串中的迭代器位置2
查找結(jié)果子串的在源串后面的位置)
查找成功:3
查找結(jié)果子串的在源串中的迭代器位置3
查找結(jié)果子串的在源串后面的位置a
替換(Replace)
最后一種操作稱(chēng)為「替換」,即將正則表達(dá)式內(nèi)容替換為指定內(nèi)容,regex庫(kù)用模板函數(shù)std::regex_replace提供「替換」操作。
string regex_replace(string s,regex p,string replace_str)?? ?//有其他重載用法
現(xiàn)在,給定一個(gè)數(shù)據(jù)為"he…ll…o, worl…d!", 思考一下,如何去掉其中誤敲的“.”?
#include<iostream> #include<regex> using namespace std; int main() { ?? ?char data[] = "he...ll..o, worl..d!"; ?? ?regex reg("\\.");?? ?//正則匹配點(diǎn). ?? ?cout << regex_replace(data, reg, "");?? ?//將正則匹配到的點(diǎn)替換成無(wú),即刪除點(diǎn) ?? ?return 0; }
hello, world!
刪除了沒(méi)必要的點(diǎn),是不是賊方便…
對(duì)字符串data中與模式匹配的所有子串進(jìn)行相應(yīng)的字符串替換,替換字符串引用匹配子串中的內(nèi)容,引用方法如下
轉(zhuǎn)義序列 | 替換為 |
---|---|
$n | 匹配第n個(gè)捕捉組的字符串。例如$l表示第一個(gè)捕捉組,$2表示第二個(gè),依此類(lèi)推 |
$& | 匹配整個(gè)正則表達(dá)式的字符串,等同于$0 |
$` | 在源字符串中,在匹配正則表達(dá)式的子字符串左側(cè)的部分 |
$’ | 在源字符串中,在匹配正則表達(dá)式的子字符串右側(cè)的部分 |
$$ | 美元符號(hào) |
#include<iostream> #include<regex> using namespace std; int main() { char data[] = "001-Neo,002-Lucia"; regex reg("(\\d+)-(\\w+)"); cout << regex_replace(data, reg, "$1 name=$2"); return 0; }
001 name=Neo,002 name=Lucia
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Opencv Hough算法實(shí)現(xiàn)圖片中直線檢測(cè)
這篇文章主要為大家詳細(xì)介紹了Opencv Hough算法實(shí)現(xiàn)圖片中直線檢測(cè),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12Qt實(shí)現(xiàn)蘋(píng)果狀態(tài)切換按鈕
這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)蘋(píng)果狀態(tài)切換按鈕,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08C語(yǔ)言實(shí)現(xiàn)餐飲點(diǎn)餐管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)餐飲點(diǎn)餐管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01C++實(shí)現(xiàn)LeetCode(154.尋找旋轉(zhuǎn)有序數(shù)組的最小值之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(154.尋找旋轉(zhuǎn)有序數(shù)組的最小值之二),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單通訊錄
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易掃雷游戲詳解
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08c++中虛函數(shù)和純虛函數(shù)的作用與區(qū)別
這篇文章主要介紹了c++中虛函數(shù)和純虛函數(shù)的作用與區(qū)別,需要的朋友可以參考下2014-07-07