正则表达式使用技巧整理
测试工具
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日。这次重新排版上传供读者阅读参考,感谢~!