您好,登錄后才能下訂單哦!
今天小編給大家分享一下c++正則表達式怎么應用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
1.檢查一個串是否包含某種形式的子串;
2.將匹配的子串替換
3.從某個串中取出符合條件的子串。
普通字符包括沒有顯式指定為元字符的所有可打印和不可打印字符。這包括所有大寫和小寫字母、所有數字、所有標點符號和一些其他符號。
特殊字符是正則表達式里有特殊含義的字符,也是正則表達式的核心匹配語法。參見下表:
特殊字符 | 描述 |
$ | 匹配輸入字符串的末尾位置 |
* | 匹配前面的子表達零次或多次 |
+ | 匹配前面的子表達零次或多次 |
[ | 標記一個中括號表達式開始 |
? | 匹配前面子表達式零次或一次,或指明非貪婪限定符 |
\ | 將下一個字符標記為或特殊字符、或原義字符、或向后引用、或八進制轉義符。例如,n匹配字符n。\n 匹配換行符。序列\\匹配\字符,而\則匹配‘(·字符。 |
~ | 匹配輸人字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字符集合。 |
{ | 標記限定符表達式開始 |
\| | 指明兩項之間的一個選擇 |
補充:
(,)標記一個子表達式的開始和結束位置,子表達式可以供以后使用
. :匹配前面除\n之外的任何單字符
限定符用來指定正則表達式的一個給定的組件必須要出現多少次才能滿足匹配。見下表:
字符 | 描述 |
* | 匹配前面的子表達式零次或多次。例如,foo* 能匹配 fo 以及 foooo。* 等價于 {0,}。 |
+ | 匹配前面的子表達式一次或多次。例如,foo+ 能匹配 foo 以及 foooo,但不能匹配 fo。+ 等價于 {1,}。 |
? | 匹配前面的子表達式零次或一次。例如,Your(s)? 可以匹配 Your 或 Yours 中的 Your 。? 等價于 {0,1}。 |
{n} | n 是一個非負整數。匹配確定的 n 次。例如,o{2} 不能匹配 for 中的 o,但是能匹配 foo 中的兩個 o。 |
{n,} | n 是一個非負整數。至少匹配 n 次。例如,o{2,} 不能匹配 for 中的 o,但能匹配 foooooo 中的所有 o。o{1,} 等價于 o+。o{0,} 則等價于 o*。 |
{n,m} | m 和 n 均為非負整數,其中 n 小于等于 m。最少匹配 n 次且最多匹配 m 次。例如, o{1,3} 將匹配 foooooo 中的前三個 o。o{0,1} 等價于 o?。注意,在逗號和兩個數之 間不能有空格。 |
對字符串內容進行匹配的最常見手段就是使用正則表達式。可惜在傳統 C++ 中正則表達式一直沒 有得到語言層面的支持,沒有納入標準庫,而 C++ 作為一門高性能語言,在后臺服務的開發中,對 URL 資源鏈接進行判斷時,使用正則表達式也是工業界最為成熟的普遍做法。
C++11 提供的正則表達式庫操作 std::string 對象,模式 std::regex (本質是 std::basic_regex) 進行初始化,通過 std::regex_match 進行匹配,從而產生 std::smatch(本質是 std::match_results 對象)。
我們通過一個簡單的例子來簡單介紹這個庫的使用。考慮下面的正則表達式:
[a-z]+\.txt: 在這個正則表達式中, [a-z] 表示匹配一個小寫字母, + 可以使前面的表達式匹配多 次,因此 [a-z]+ 能夠匹配一個小寫字母組成的字符串。在正則表達式中一個 . 表示匹配任意字 符,而 \. 則表示匹配字符 .,最后的 txt 表示嚴格匹配 txt 則三個字母。因此這個正則表達式的 所要匹配的內容就是由純小寫字母組成的文本文件。
std::regex_match 用于匹配字符串和正則表達式,有很多不同的重載形式。最簡單的一個形式就是 傳入 std::string 以及一個 std::regex 進行匹配,當匹配成功時,會返回 true,否則返回 false。例 如:
#include <iostream> #include <string> #include <regex> int main() { std::string fnames[] = {"foo.txt", "bar.txt", "test", "a0.txt", "AAA.txt"}; // 在 C++ 中 \ 會被作為字符串內的轉義符,為使 \. 作為正則表達式傳遞進去生效,需要對 \ 進行二次轉義,從而有 \\. std::regex txt_regex("[a-z]+\\.txt"); for (const auto &fname: fnames) std::cout << fname << ": " << std::regex_match(fname, txt_regex) << std::endl; }
結果:
foo.txt: 1
bar.txt: 1
test: 0
a0.txt: 0
AAA.txt: 0
另一種常用的形式就是依次傳入 std::string/std::smatch/std::regex 三個參數,其中 std::smatch 的本質其實是 std::match_results。在標準庫中,std::smatch 被定義為了 std::match_results, 也就是一個子串迭代器類型的 match_results。使用 std::smatch 可以方便的對匹配的結果進行獲取
#include<iostream> #include<string> #include<regex> int main() { std::string fnames[] = {"foo.txt", "bar.txt", "test", "a0.txt", "AAA.txt"}; // 在 C++ 中 \ 會被作為字符串內的轉義符,為使 \. 作為正則表達式傳遞進去生效,需要 std::regex base_regex("([a-z]+)\\.txt"); std::match_results<std::string::const_iterator> base_match; for(const auto& fname : fnames) { if(std::regex_match(fname,base_match,base_regex)) { // std::smatch 的第一個元素匹配整個字符串 // std::smatch 的第二個元素匹配了第一個括號表達 if (base_match.size() == 2){ std::string base = base_match[1].str(); std::cout << "sub-match[0]: " << base_match[0].str() << std::endl; std::cout << fname << " sub-match[1]: " << base << std::endl; } } } }
sub-match[0]: foo.txt foo.txt
sub-match[1]: foo
sub-match[0]: bar.txt bar.txt
sub-match[1]: bar
regex_search:搜索匹配,即搜索字符串中存在符合規則的子字符串。
regex_replace: 替換匹配,即可以將符合匹配規則的子字符串替換為其他字符串。(會改變字符串本身)
測試代碼 regex_search:
#include<regex> #include<string> #include<iostream> int main() { std::string str = "hello2012-12-12world!!!!!"; std::match_results<std::string::const_iterator> match; std::regex pattern("(\\d{4})-(\\d{1,2})-(\\d{1,2})"); if (std::regex_search(str,match,pattern)) { for (size_t i = 1; i < match.size(); ++i) { std::cout << match[i] <<std:: endl; } } return 0; } // 2012 12 12
測試代碼:regex_replace
#include<regex> #include<string> #include<iostream> using namespace std; int main() { string str = "2019-08-07"; cout << regex_replace(str, regex("-"), "/") << endl; cout << str << endl; return 0; }
數字 : ^[0-9]*$
n 位的數字 : ^\d{n}$
至少 n 位的數字 : ^\d{n,}$
m-n 位的數字 : ^\d{m,n}$
零和非零開頭的數字 : ^(0|[1-9][0-9]*)$
非零開頭的最多帶兩位小數的數字 : ^([1-9][0-9]*)+(.[0-9]{1,2})?$
帶 1~2 位小數的正數或負數 : ^(\-)?\d+(\.\d{1,2})?$
正數 , 負數 , 和小數 : ^(\-|\+)?\d+(\.\d+)?$
有兩位小數的正實數 : ^[0-9]+(.[0-9]{2})?$
有 1~3 位小數的正實數 : ^[0-9]+(.[0-9]{1,3})?$
非零的正整數 : ^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的負整數 : ^\-[1-9][]0-9″*$ 或 ^-[1-9]\d*$
非負整數 : ^\d+$ 或 ^[1-9]\d*|0$
非正整數 : ^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非負浮點數 : ^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮點數 : ^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮點數 : ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
負浮點數 : ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮點數 : ^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
漢字 : ^[\u4e00-\u9fa5]{0,}$
英文和數字 : ^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
長度為 3~20 的所有字符 : ^.{3,20}$
由 26 個英文字母組成的字符串 : ^[A-Za-z]+$
由 26 個大寫英文字母組成的字符串 : ^[A-Z]+$
由 26 個小寫英文字母組成的字符串 : ^[a-z]+$
由數字和 26 個英文字母組成的字符串 : ^[A-Za-z0-9]+$
由數字 , 26 個英文字母或者下劃線組成的字符串 : ^\w+$ 或 ^\w{3,20}$
中文 , 英文 , 數字包括下劃線 : ^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文 , 英文 , 數字但不包括下劃線等符號 : ^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以輸入含有^%&',;=?$\"等字符 : [^%&',;=?$\x22]+
禁止輸入含有 ~ 的字符 : [^~\x22]+
Email 地址 : ^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名 : [a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL : [a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手機號碼 : ^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
電話號碼("XXX-XXXXXXX" , "XXXX-XXXXXXXX" , "XXX-XXXXXXX" , "XXX-XXXXXXXX" , "XXXXXXX"和"XXXXXXXX) : ^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$
國內電話號碼 (0511-4405222 , 021-87888822) : \d{3}-\d{8}|\d{4}-\d{7}
身份證號 (15 位 , 18 位數字) : ^\d{15}|\d{18}$
短身份證號碼 (數字 , 字母 x 結尾) : ^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
帳號是否合法(字母開頭,允許 5~16 字節,允許字母數字下劃線) : ^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密碼 (以字母開頭,長度在 6~18 之間,只能包含字母 , 數字和下劃線) : ^[a-zA-Z]\w{5,17}$
強密碼 (必須包含大小寫字母和數字的組合,不能使用特殊字符,長度在 8~10 之間) : ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式 : ^\d{4}-\d{1,2}-\d{1,2}
一年的 12 個月(01~09和1~12) : ^(0?[1-9]|1[0-2])$
一個月的 31 天(01~09和1~31) : ^((0?[1-9])|((1|2)[0-9])|30|31)$
在C++中,對于特殊字符,需要使用轉義字符. 因此,匹配數字的\d,需要寫成\d這種格式.
經典的三部曲匹配:
1.先寫pattern. string pattern = {“XXXX”};
2.使用re. regex re(pattern);
3.match. bool rs = regex_match(mobile, re);
4.regex_match在匹配一次后即返回結果,如果期望進行多次匹配,需要用到regex_iterator.std::regex_iterator<std::string::iterator> rit(result.begin(), result.end(), re); 匹配結果的輸出可以利用cmatch.regex_match(rit->str().c_str(), cm, re);這里面cm的內容與正則表達式pattern是對應匹配的. 具體可參考matchPriceInfo方法.
以上就是“c++正則表達式怎么應用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。