正則表達式使用技巧整理


測試工具

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日。這次重新排版上傳供讀者閱讀參考,感謝~!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM