測試工具
https://c.runoob.com/front-end/854
常用技巧
\S: 表示匹配任何非空白字符。等價於 [^ \f\n\r\t\v]。
\s: 表示匹配匹配任何空白字符,包括空格、制表符、換頁符等等。等價於 [ \f\n\r\t\v]。
[\s\S]:表示出現空白和非空白中的任意一個字符,即是任意字符
\w: 匹配字母或數字或下划線或漢字 等價於 ‘[A-Za-z0-9_]’。
\s : 匹配任意的空白符
\d : 匹配數字
\b : 匹配單詞的開始或結束
*: 匹配前面的子表達式零次或多次。要匹配 * 字符,請使用 \*。
+: 匹配前面的子表達式一次或多次。要匹配 + 字符,請使用 \+。
|: 指明兩項之間的一個選擇。要匹配 |,請使用 \|。
^: 匹配輸入字符串的開始位置,除非在方括號表達式中使用,此時它表示不接受該字 符集合。要匹配 ^ 字符本身,請使用 \^。
{n,m} 表示n 到m 次
典型例子
正則表達式匹配雙引號之間的數據 但不包括雙引號
\"([^\"]*)\"
樣本:
abcs"fdsdfs" ffd fs "fwert423wr" "fsd fsf,ewrer"
匹配結果:
"fdsdfs" "fwert wtewr" "fsd fsf,ewrer"
分割字符串但是不分割字符串中引號中間的數據
(?<!\"[^,]+),(?![^,]+\") (C#)Regex.Split
(\w|\.)+[^,]|\"[^"]*\"|\w (c++)
樣本:11211,210161,\"SHRINK FILM, 23 W X .0015MIL\",49.95,RM1 ,1
匹配結果:11211 210161 "SHRINK FILM, 23 W X .0015MIL" 49.95 RM1 1
按空格分隔 但不分隔引號中的空格
\w+\:(\w+|"[^"]*")+?
樣本:name:Lily age:23 class:"class 1"
匹配結果:name:Lily age:23 class:"class 1"
另一小例---局部批對字符串
上海?[^,。、\s]+公司
樣本: 1 上海汽車集團股份有限公司 51 上海春秋國際旅行社(集團)有限公司
2 交通銀行股份有限公司 52 上海斐訊數據通信技術有限公司
3 上海浦東發展銀行股份有限公司 53 康德樂醫葯有限公司
4 中國太平洋保險(集團)股份有限公司 54 上海機場(集團)有限公司
匹配結果:
上海汽車集團股份有限公司
上海春秋國際旅行社(集團)有限公司
上海斐訊數據通信技術有限公司
上海浦東發展銀行股份有限公司
上海機場(集團)有限公司
獲取以-成對的字符串
\w+\s*-(\s*[^,;]+)
樣本:
fsd-fsdfs fds-fsdfs,werfsd-fewrwrw;fewrwer,fdf -fdf fsdew- fd90
匹配結果:
fsd-fsdfs
fds-fsdfs
werfsd-fewrwrw
fdf -fdf
fsdew- fd90
另一小例
[^,"]+|,,|(?:"[^,"]*"[^"]*"[^"]*)"|"(?:[^"])*"
樣本: your dollors,10000, 27 years old ,,"10,000","it is "10 Grand",baby",10k
匹配結果: your dollors 10000 27 years old ,, "10,000" "it is "10 Grand",baby" 10k
C++ 代碼 獲取匹配的字符串數組或替換
#include <regex>
#include <string>
// 使用類 std::regex_iterator 來進行多次搜索.
static std::string _strs = "... ..." ;
std::regex _regex("<img [^>]+>");
std::cout << "sregex_iterator ====" << std::endl;
auto words_begin =
std::sregex_iterator(_strs.begin(), _strs.end(), _regex);
auto words_end = std::sregex_iterator();
for (std::sregex_iterator i = words_begin; i != words_end; ++i)
{
std::smatch match = *i;
std::string match_str = match.str();
std::cout << match_str << '\n';
}
// 把所有 img src 的絕對路徑替換為 images 開始的相對路徑.使用分組即可.
std::regex img_regex("(<img [^>]*src=[\"']{1})([^\"']*)\\\\(images\\\\[^\"']*[\"']{1}[^>]*>)");
std::smatch color_match;
std::string rep = "$1$3";
std::string tmp = std::regex_replace(kHtmlSnippet,img_regex,rep);
std::cout << tmp << std::endl;
小例講解
【1】
a.*c
匹配以a為開頭,c為結尾的字符串,其中. 代表任何字符,* 代表零次或者多次
【2】
ab+c
匹配以a為開頭,c為結尾,並且其中只出現一次或者多次b的字符串,其中+ 代表前面一個字符匹配一次或者多次
【3】
ab{2,3}c
匹配以a為開頭,c為結尾,並且其中只出現2次到3次b的字符串,{} 一般用來定義匹配長度
【4】
a:?\w+
a為開頭,第二個字符”:”出現的次數0次或者1次,接下來多次匹配字母或數字或下划線或漢字,其中? 表示前面的字符匹配0次或者1次
【5】
\"([^\"]*)\"
匹配雙引號之間的數據
如 “abc” “fsds ,werw”
即 “ 多個字符,但是不包含引號 ” , 即 匹配字符串,開頭是”,結尾是”,中間是沒有”的字符串(零次或多次除了”的字符),其中^意思為除了什么字符, 注意轉義字符 \ , \” 為匹配引號,[...]*中括號里面匹配零次或多次
【6】
\w+|\"([^\"]*)\"
解釋:
加了 | 或運算 。即 兩個表達式
1.\w+ 匹配一次或者多次字母或數字或下划線或漢字
2.\"([^\"]*)\" 同【5】!
因此,如果樣本為:abc,dfse,"few,few,f"
結果為:abc dfse "few,few,f"
此例也可改為:[^," ]+|\"([^\"]*)\" ,因為樣本中只有 , 和 “ 兩種特殊字符,所以可以排除法去匹配,匹配一次或多次除了,”的字符
【7】
\w+\:(\w+|"[^"]*")
以:為連接符連接成一組,按空格分隔,但不分隔引號中的空格
樣本:name:Lily age:23 class:"class 1"
匹配結果:name:Lily age:23 class:"class 1"
分解成兩塊來匹配,第一塊為冒號前部,\w+,匹配一次或多次字母或數字或下划線或漢字。第二塊為6.案例所述的。兩塊結合,中間加上:
即 \w+ \: \w+|"[^"]*"
【8】
(\w|\.)+[^,]|\"[^"]*\"|\w
如果數據是這樣 11211,210161,"SHRINK FILM, 23 W X .0015MIL",49.95,RM1 ,1
需要處理成如下格式的數據: 11211 210161 "SHRINK FILM, 23 W X .0015MIL" 49.95 RM1 1
解釋:分為三部分解析
1.(\w|\.)+[^,] 匹配一次或多次 字母或數字或下划線或漢字
(\w)或者是”.”號的字符,並且最后字符不是”,”
(...)+ 表示括號中的字符允許出現一次或者多次
[^,] 表示除了”,”字符,即以”,”結束
2.\"[^"]*\" 匹配開頭結尾是”的字符(串),即如果不是”字
符的話都是引號中的字符
3.\w 匹配有且僅有一次字母或數字或下划線或漢字
三部分用 | 來連接,表示三種情況任意一種符合,則表達式成立,即或運算。注意其中的轉義字符使用
【9】
[^,"]+|,,|(?:"[^,"]*"[^"]*"[^"]*)"|"(?:[^"])*"
樣本:your dollors,10000, 27 years old ,,”10,000”,”it is “10 Grand”,baby”,10k
匹配結果:your dollors 10000 27 years old 空字段 10,000 it is “10 Grand”,baby 10k
【難點】在於“10,000”和“it is “10 Grand”,baby”,雙引號中嵌套雙引號和逗號
1、[^,"]+可以獲取之前用逗號和雙引號分割的字段,但是這顯然不足以將這七個字段完全正確的分割開;
2、雙引號中包含逗號或雙引號之間的文本,"(?:[^"]|"")*"
3、雙引號嵌套:如果是雙層嵌套,可以用表達式"[^,"]*"[^"]*"[^"]*"
最終:[^,"]+|,,|(?:"[^,"]*"[^"]*"[^"]*)"|"(?:[^"])*"
分解:
[^,"]+ #普通字段
,, #空字段
(?:"[^,"]*"[^"]*"[^"]*") #雙層雙引號嵌套
"(?:[^"])*" #雙引號嵌套逗號
【10】
[^\/^\[^,](\w)+\s?:(\s?#?)(\w+|\[(\d|,|\s)+\]|\"[^"]+\")+
樣本://#_drag: 1, #command : #killApp, #delay: 20, #path : "D:\FLFQ_SOFT\Launcher EXE v_2.2.5\launcher.exe", #winTitle : "Launcher", #closeErrors : 1
匹配結果:
#_drag: 1
#command : #killApp
#delay: 20
#path : "D:\FLFQ_SOFT\Launcher EXE v_2.2.5\launcher.exe"
#winTitle : "Launcher"
#closeErrors : 1
兩個部分,以:為切分點
1. [^\/^\[^, ](\\w)+\\s?
匹配字符串,開頭不是/, [ , 或者空格的,接着是一個或多個 字母或數字或
下划線或漢字 的字符串,最后0個或1個空格
2. (\s?#?)(\w+|\[(\d|,|\s)+\]|\"[^"]+\")+
(\s?#?) 匹配字符串,開頭有0個或者1個空格,接下來有0個或1個#,
接下來的字符串分情況討論:
1)\w+ 一個或多個 字母或數字或下划線或漢字 的字符串
2)\[(\d|,|\s)+\] 以[ ... ]為數據結構的字符串,其中包括一個或多個 數字,逗號,空格
3)\"[^"]+\" 以” ... “為數據結構的字符串,其中包括不帶引號的任何字符(串)
1)2)3)三種情況或運算,匹配1次或者多次,套用( ... )+
兩部分以:連接在一起進行配對
【11】
#?\w+|\d[^\s]+|\"[^"]+\"|\[(\d|,|\s)+\]
解釋:
樣本: #path : "D:\FLFQ_SOFT\Launcher EXE v_2.2.5\launcher.exe"
#winTitle : "Launcher"
#clientRect: [0, 0, 1024, 768]
匹配結果:
"D:\FLFQ_SOFT\Launcher EXE v_2.2.5\launcher.exe"
"Launcher"
[0, 0, 1024, 768]
分四個部分進行或運算匹配
1. #?\w+
開頭0個或一個#,一個或多個 字母或數字或下划線或漢字
2. \d[^\s]+
有一個數字的,后面不帶空格的字符串
3. \"[^"]+\"
“...”的字符串,其中包含不帶“的字符串
4. \[(\d|,|\s)+\]
[...]的字符串,其中包含一個或多個 數字、空格、逗號
四個表達式一起或運算匹配到aaa:bbb中的bbb字符串
參考
https://blog.csdn.net/qq_30034925/article/details/70216525 正則表達式詳細用法
http://help.locoy.com/Document/Learn_Regex_For_30_Minutes.htm 正則表達式30分鍾入門教程
https://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html 最全的常用正則表達式大全——包括校驗數字、字符、一些特殊的需求等等
https://blog.csdn.net/fengbingchun/article/details/54835571 正則表達式簡介及在C++11中的簡單使用
https://blog.csdn.net/fangjin_kl/article/details/79803120 C++11 之 regex 正則表達式
https://blog.csdn.net/infoworld/article/details/50946545 [C/C++11][初級][使用正則表達式庫regex]
https://blog.csdn.net/AirTesla/article/details/65936559 正則表達式—解析CSV文件
PS
此篇博文內容編寫於2018年12月5日。這次重新排版上傳供讀者閱讀參考,感謝~!