柚子快報(bào)邀請碼778899分享:正則表達(dá)式 regex
柚子快報(bào)邀請碼778899分享:正則表達(dá)式 regex
文章目錄
參考單詞邊界捕獲組反向引用 與 提取數(shù)據(jù)先行斷言非捕獲括號貪婪匹配 & 惰性匹配
參考
https://blog.csdn.net/Conradine_Lian/article/details/108890595
regex可以很簡單 也可以很復(fù)雜
/* 限定符 修飾前面的一個(gè)字符,可以是元字符
* 重復(fù)0次或更多次
+ 重復(fù)1次或更多次 []里的+就只是一個(gè)"+"字符了
? 重復(fù)0或1次
{n} 重復(fù)n次
{n,} 重復(fù)n或更多次
{n,m} 重復(fù)n到m次
例:abc* 表示可匹配 以ab 開頭后面沒有c或有多個(gè)c
\d{5} 表示\d匹配到的數(shù)字連續(xù)出現(xiàn)5次
元字符 匹配單個(gè)字符
. 匹配除換行符以外的任意單個(gè)字符
^ 表示匹配行首的文本(以什么表達(dá)式開始)
$ 表示匹配行尾的文本(以什么表達(dá)式結(jié)束)
\s 匹配任意的空白
\S 匹配任意不是空白符的字符
\d 匹配數(shù)字
\D 匹配任意非數(shù)字的字符
\w 匹配字母或數(shù)字或下劃線
\W 匹配不是字母數(shù)字下劃線的字符
\b 匹配一個(gè)單詞邊界 所謂'單詞邊界' 請參考https://blog.csdn.net/weixin_42636353/article/details/82466892
\B 非字邊界匹配。
其他
[] 匹配其中的任意一個(gè)字符 相當(dāng)于或的意思 [abcd]
[^] 匹配除了方括號內(nèi)的字符 相當(dāng)于取反 [^abcd]
[n-m] 匹配n到m范圍內(nèi)的任意 一個(gè)字符 [0-9] 這是\d的全寫 [^0-9] 這是\D的全寫 可和其她范圍連用 [0-9A-z_]
\ 轉(zhuǎn)義符 轉(zhuǎn)特殊字符為要匹配的字符 \. 匹配. \\ 匹配\ \/ 匹配/
| 前面一大部分或者后面一大部分 如果要改變范圍可用() 如 b(o|a)y 匹配boy bay
[\u4e00-\u9fa5] 匹配漢字
正則表達(dá)式還有很多還有待深究
單詞邊界
單詞邊界是指一個(gè)單詞的開頭或結(jié)尾,或者一個(gè)單詞和一個(gè)非單詞字符之間的位置。
在正則表達(dá)式中,單詞邊界是用\b表示,它并非指字符,而是指單詞和非單詞之間的位置,比如一個(gè)單詞后面跟著一個(gè)空格,那么這個(gè)空格和這個(gè)單詞之間就是一個(gè)單詞邊界。除了單詞邊界和非單詞邊界表示位置外,行首^和行尾$也是表示位置。
捕獲組
(組) 用圓括號分組
// 原始字符串,由 '|' 分隔
std::string s = "part1|part2|part3";
// 正則表達(dá)式模式,匹配由 '|' 分隔的第二部分
// 我們使用捕獲組來保留前后部分
std::regex pattern("(\\w+)\\|(\\w+)\\|(\\w+)");
// 替換字符串,捕獲到的用replacement的內(nèi)容替換 下面這是種拼接
std::string replacement = "$1|new_part|$3";
// 使用正則表達(dá)式進(jìn)行替換
std::string result = std::regex_replace(s, pattern, replacement);
// 輸出替換后的字符串
std::cout << result << std::endl;
輸出:
part1|new_part|part3
// 原始字符串
std::string s = "The quick brown fox jumps over the lazy dog dog";
// 正則表達(dá)式,匹配重復(fù)的單詞
std::regex e("(\\b\\w+)\\s+\\1\\b");
// 替換字符串,其中\(zhòng)\1是一個(gè)反向引用,引用了第一個(gè)捕獲組
std::string r = "$1"; // 只保留第一個(gè)匹配的單詞 或者"555"替換 上面的 重復(fù)的dog
// 執(zhí)行替換
std::string result = std::regex_replace(s, e, r);
// 輸出結(jié)果
std::cout << result << std::endl;
輸出:
The quick brown fox jumps over the lazy dog
反向引用 與 提取數(shù)據(jù)
上面$1 (這里1是組號 表示第一個(gè)組) 就是提取匹配組匹配到的數(shù)據(jù)std::string s = "I have an apple apple2.";
std::regex e(R"((apple)\s+(apple2))");
std::string r = R"($2 orange1)"; // 使用$1引用第一個(gè)捕獲組,即第一個(gè)"apple"
std::string result = std::regex_replace(s, e, r); //
std::cout< >.R"()"是CLion編譯器提供支持的被其修的字面字符量不需要手動轉(zhuǎn)義轉(zhuǎn)義字符的寫法 輸出: I have an apple2 orange1. 反向引用 假設(shè)你想在一個(gè)字符串中查找連續(xù)重復(fù)的單詞,如"the the"或"is is"。你可以使用以下正則表達(dá)式std::regex e("(\\b\\w+)\\s+\\1\\b"); 上面的 \1 就是反向引用第一組的內(nèi)容 先行斷言 正向先行斷言 (?=p) 匹配后面緊挨著p的字符, p可以是多個(gè)字符 也可以是匹配規(guī)則std::string s = "123 abc 456, 7890, more text 123"; std::regex e("(\\d+)(?=,)"); // 匹配數(shù)字,后面緊跟著一個(gè)逗號(但不包括逗號) // 使用sregex_iterator進(jìn)行匹配 std::sregex_iterator begin(s.begin(), s.end(), e); std::sregex_iterator end; for (std::sregex_iterator i = begin; i != end; ++i) { std::smatch match = *i; std::string match_str = match.str(); std::cout << "Matched: " << match_str << std::endl; } 輸出: 456 7890 std::string s = "123 abc 456, 7890, more text 123"; std::regex e("(\\d+)(?= [A-z])"); // 匹配后面是空格,然后后面緊跟著一個(gè)字母的數(shù)字 // 使用sregex_iterator進(jìn)行匹配 std::sregex_iterator begin(s.begin(), s.end(), e); std::sregex_iterator end; for (std::sregex_iterator i = begin; i != end; ++i) { std::smatch match = *i; std::string match_str = match.str(); std::cout << "Matched: " << match_str << std::endl; } 輸出: 123 負(fù)向先行斷言 (?!p) 匹配 后面沒有緊挨著p的字符注意事項(xiàng) 先行斷言是一種零寬斷言,這意味著它不會消耗任何字符,只是簡單地檢查后續(xù)字符是否滿足某個(gè)條件。先行斷言在性能上可能比較昂貴,因?yàn)樗枰跋蚯翱础眮頇z查條件是否滿足。在復(fù)雜的正則表達(dá)式或大型文本中,這可能會影響匹配的速度。 非捕獲括號 (?:p) 分組而不捕獲,看起來像分組, 其實(shí)不算進(jìn)分組的引用里面所以無法$1 \1這樣引用到非捕獲括號匹配的數(shù)據(jù)因?yàn)樗鼪]有捕獲這意味著如果混合在捕獲分組里, 也不會影響捕獲分組的引用順序在一些需要把其作為匹配條件, 但又不需要引用到其匹配的字符的場景下可能有用 std::string s = "123 abc 456,456 7890, more text 123"; std::regex e("(123).*(?:abc).*(456).*(\\2)");//這里第二個(gè)分組是456 引用它 std::string r = R"($2 orange1)"; // 使用$2引用第二個(gè)捕獲組,即 456 std::string result = std::regex_replace(s, e, r); // std::cout< 輸出: 456 orange1 7890, more text 123 貪婪匹配 & 惰性匹配 默認(rèn)是貪婪匹配, 盡可能多的匹配 比如我要匹配以 lib 開始的 以 .dll 結(jié)尾的 std::string long_string = "sadfd-_libshdf*-.-.dll sadf libhello.dll libsome-1.0.dll aaa"; // 定義正則表達(dá)式模式 std::regex pattern(R"(lib.*\.dll)"); // 使用 sregex_iterator 查找所有匹配項(xiàng) auto begin = std::sregex_iterator(long_string.begin(), long_string.end(), pattern); auto end = std::sregex_iterator(); // 遍歷所有匹配項(xiàng)并輸出 for (std::sregex_iterator i = begin; i != end; ++i) { std::smatch match = *i; // 獲取當(dāng)前匹配項(xiàng) std::cout << "'" << match.str() << "' 在長字符串中匹配成功\n"; } 輸出: ‘libshdf*-.-.dll sadf libhello.dll libsome-1.0.dll’ 在長字符串中匹配成功 但里面嵌套了一些符合要求的 如果我想要就近結(jié)束一段匹配, 就需要使用惰性匹配 在量詞后面加個(gè)問號就能實(shí)現(xiàn)惰性匹配 std::string long_string = "sadfd-_libshdf*-.-.dll sadf libhello.dll libsome-1.0.dll aaa"; // 定義正則表達(dá)式模式 std::regex pattern(R"(lib.*?\.dll)"); // 使用 sregex_iterator 查找所有匹配項(xiàng) auto begin = std::sregex_iterator(long_string.begin(), long_string.end(), pattern); auto end = std::sregex_iterator(); // 遍歷所有匹配項(xiàng)并輸出 for (std::sregex_iterator i = begin; i != end; ++i) { std::smatch match = *i; // 獲取當(dāng)前匹配項(xiàng) std::cout << "'" << match.str() << "' 在長字符串中匹配成功\n"; } 輸出: ‘libshdf*-.-.dll’ 在長字符串中匹配成功 ‘libhello.dll’ 在長字符串中匹配成功 ‘libsome-1.0.dll’ 在長字符串中匹配成功 柚子快報(bào)邀請碼778899分享:正則表達(dá)式 regex 精彩鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。