zoukankan      html  css  js  c++  java
  • 正则表达式使用技巧整理

    测试工具

    https://c.runoob.com/front-end/854

    常用技巧

    S: 	表示匹配任何非空白字符。等价于 [^ f
    
    	v]。
    s: 	表示匹配匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f
    
    	v]。
    [sS]:表示出现空白和非空白中的任意一个字符,即是任意字符
    w: 	匹配字母或数字或下划线或汉字 等价于 ‘[A-Za-z0-9_]’。 
    s :	匹配任意的空白符 
    d :	匹配数字 
     :	匹配单词的开始或结束 
    *: 	匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。
    +:  	匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
    |:	指明两项之间的一个选择。要匹配 |,请使用 |。
    ^:	匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字	符集合。要匹配 ^ 字符本身,请使用 ^。
    {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 << '
    ';
    }
    
    // 把所有 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_SOFTLauncher EXE v_2.2.5launcher.exe", #winTitle : "Launcher", #closeErrors : 1

    匹配结果:
    #_drag: 1
    #command : #killApp
    #delay: 20
    #path : "D:FLFQ_SOFTLauncher EXE v_2.2.5launcher.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_SOFTLauncher EXE v_2.2.5launcher.exe"
    		 #winTitle : "Launcher"
    		 #clientRect: [0, 0, 1024, 768]
    匹配结果:
    "D:FLFQ_SOFTLauncher EXE v_2.2.5launcher.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日。这次重新排版上传供读者阅读参考,感谢~!

  • 相关阅读:
    Beta冲刺 5
    Beta冲刺 4
    Beta冲刺 3
    Beta冲刺 2
    Beta冲刺 1
    项目评测博客
    Beta冲刺前准备
    Alpha 冲刺11——总结
    Alpha冲刺10
    Alpha冲刺9
  • 原文地址:https://www.cnblogs.com/sharpeye/p/15331867.html
Copyright © 2011-2022 走看看