正则表达式

一、常用元字符

1、【\b】【.】

(1)功能:
【\b】代表着单词的开头或结尾,也就是单词的分界处;只匹配一个位置。
【.】匹配除了换行符以外的任意字符

(2)例子

例1、精确地查找hi这个单词:\bhi\b

例2、查找hi,并且hi后面不远处跟着一个Lucy:\bhi\b.*\bLucy\b
注:【*】(是限定符,而非元字符)代表的不是字符,也不是位置,而是数量,它指定【*】前边的内容可以连续重复使用任意次;
【.*】连在一起就意味着任意数量的不包含换行的字符。

2、【\d】

(1)功能:【\d】匹配一位数字(0,或1,或2,或……)。

(2)例子

例1、0\d\d-\d\d\d\d\d\d\d\d表示:以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字,也就是中国的电话号码。

例2、0\d{2}-\d{8},是例1的简化写法,\d后面的{2}({8})的意思是前面\d必须连续重复匹配2次(8次)。
注:【-】不是元字符,只匹配它本身(连字符)。

3、【\s】【\w】

(1)功能
【\s】匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等
【\w】匹配字母或数字或下划线或汉字等

(2)例子

例1、\ba\w*\b:以字母a开头的单词,字母a后是任意数量的字母或数字。

例2、\d+:匹配1个或更多连续的数字。

例3、\b\w{6}\b: 匹配刚好6个字符的单词。
注:【+】和【*】类似(是限定符,而非元字符),不同的是【*】匹配重复任意次(可能是0次),【+】匹配重复1次或更多次(至少1次)

4、【^】【$】

(1)功能
【^】匹配字符串的开始
【$】匹配字符串的结束
有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项,【^】和【$】的意义就变成了匹配行的开始处和结束处

(2)例子

例1、^\d{5,12}$:5位到12位数字

二、字符转义【\】

(1)功能
在查找【元字符】本身时,比如查找【.】或者【*】,需要在元字符之前添加【\】,来取消元字符的特殊意义,例如【.】【*】。

(2)例子

例1、www\.baidu\.com匹配www.baidu.com

例2、F:\\demo\\test匹配F:\demo\test

三、常用的限定符

【*】【+】【?】【{n}】【{n,}】【{n,m}】

(1)功能
【*】它之前的内容重复零次或更多次
【+】它之前的内容重复一次或更多次
【?】它之前的内容重复零次或一次
【{n}】它之前的内容重复n次
【{n,}】它之前的内容重复n次或更多次
【{n,m}】它之前的内容重复n到m次

2、例子

例1、hao\d+:hao后面跟一个或多个数字。

例2、^\w+:匹配一行的第一个单词或整个字符串的第一个单词。

例3、^\d{5,12}$:匹配5位到12位数字。

四、字符类【[]】

1、功能:匹配[]中给定字符中的任意一个

2、例子

例1、[aeiou]:就匹配aeiou中任意字母。

例2、[.?!]:匹配.?!中任意一个标点符号。

例3、[0-9]:匹配0到9任意一位数字。

例4、[a-z0-9A-Z_]:完全等同于\w,匹配a到z中任意一个小写字母或0到9任意一个数字或A到Z任意一个大写字母。

例5、\(?0\d{2}[) -]?\d{8}:下面详细分析
1)\(?:匹配0个或1个左括号【(】,其中\是为了转义左括号;左右括号【()】也是元字符,需要转义;
2)0:匹配一个【0】;
3)\d{2}:匹配两个数字;
4)[) -]?:匹配右括号【(】或者【-】,出现0次或1次;
5)\d{8}:匹配8个数字。
综上就是匹配电话号码,类似:(010)12345678、010-12345678、01012345678

五、分枝条件【|】

(1)功能:匹配由【|】分隔的任意一种格式

(2)例子

例1、0\d{2}-\d{8}|0\d{3}-\d{7}:分成0\d{2}-\d{8}和0\d{3}-\d{7},匹配成功任意一个就可以。

例2、\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8};分成\(0\d{2}\)[- ]?\d{8}和0\d{2}[- ]?\d{8}。

(3)注意
一定要慎重考虑各个条件的顺序!!!
因为匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管后面的条件了,貌似跟我们理解的没什么区别,但实际运用运用时就会出现差错,考虑下面两个规则:
1)\d{5}-\d{4}|\d{5}分成\d{5}-\d{4}和\d{5}
2)\d{5}|\d{5}-\d{4}分成\d{5}和\d{5}-\d{4}
是不是认为没有什么问题,那么给个实际例子:12345-6789
是不是认为两种结果都可以匹配出12345-6789这个整体,其实不是!不是!不是!实际的结果是:
如果用1)自然可以匹配出12345-6789这个整体;
如果用2)则首先匹配出12345,后边的-6789就会被丢掉,因为12345已经匹配上了\d{5},那么整个匹配\d{5}|\d{5}-\d{4}就结束了,不会再去考虑【|】后面的\d{5}-\d{4}规则了。

六、分组【()】

(1)功能:将括号内的规则作为整体

(2)例子

例1、(\d{1,3}\.){3}\d{1,3}:下面详细分析
1)(\d{1,3}\.){3}表示括号内的规则重复三次,即【\d{1,3}\.】重复3次,再具体:
2)\d{1,3}\.首先匹配1到3个数字,再匹配一个点;
3)\d{1,3}也是匹配1到3个数字。
所以会匹配出类似这样的:123.4.56.189,即类似ip地址的信息,但无法正确识别是否是合法的地址,因为类似999.999.999.999也会被匹配,所以要完全识别ip地址可以使用例2中的规则。

例2、((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)分解:
1)((2[0-4]\d|25[0-5]|[01]?\d\d?)\.) {3}和(2[0-4]\d|25[0-5]|[01]?\d\d?)
2)((2[0-4]\d|25[0-5]|[01]?\d\d?)\.)再分为(2[0-4]\d|25[0-5]|[01]?\d\d?)这个整体和\.
3)(2[0-4]\d|25[0-5]|[01]?\d\d?)再分为2[0-4]\d或25[0-5]或[01]?\d\d?
则可以匹配出合法的IP地址
注:013.012.12.12这种前面有0的IP地址也是合法的。

七、反义

(1)功能:匹配指定规则以外的任意规则
【\W】(大写)匹配任意不是字母,数字,下划线,汉字的字符
【\S】(大写)匹配任意不是空白符的字符
【\D】(大写)匹配任意非数字的字符
【\B】(大写)匹配不是单词开头或结束的位置
【[^x]】匹配除了x以外的任意字符
【[^aeiou]】匹配除了aeiou这几个字母以外的任意字符

(2)例子

例1、\S+:匹配不包含空白符的字符串。

例2、]+>:匹配用尖括号括起来的以a开头的字符串。

八、后向引用

(1)功能
简单说就是,若一个规则中包含有分组【()】,那么在这个分组之后的规则中可以使用它所匹配到的内容;再次使用时只需要调用这个分组【()】的组号即可。

(2)关于组号
如果规则中的所有分组【()】本身没有命名,则从左到右一次编号1,2……
如果规则中部分分组【()】已经有命名了,那么第一遍先从左到右为没有命名的组进行编号,第二遍从左到右为已经命名的组编号。

(3)例子

例1、\b(\w+)\b\s+\1\b:首先切分成\b(\w+)\b、\s+、\1、\b,所以:
1)\b(\w+)\b:匹配一个或多个\w,即一个或多个字母,(\w+)就是组号为1 的分组;
2)\s+:匹配一个或多个空白符;
3)\1:匹配组1即(\w+)所捕获的内容;
4)\b:结束
综上就是:几个字母+几个空格+刚才捕获的字母,比如“you  you”、“ha  ha”

(4)关于自命名
形式:(?exp)或(?'name'exp)
解释:exp表示具体的规则,?中name就是名字

九、零宽断言

(1)功能:获取特定的位置
【(?=exp)】匹配exp前面的位置,也叫做‘零宽度正预测先行断言’
【(?<=exp)】匹配exp后面的位置,也叫做‘零宽度正回顾后发断言’
【(?!exp)】匹配后面跟的不是exp的位置
【(?

(2)例子

例1、((?<=\d)\d{3})+\b,拆分:((?<=\d)\d{3})+和\b
1)((?<=\d)\d{3})+拆成((?<=\d)\d{3})和+,即((?<=\d)\d{3})重复至少1次;
2)((?<=\d)\d{3})拆成(?<=\d)和\d{3},即(?<=\d)后有3个数字;
3)  (?<=\d)表示取数字【\d】后面的位置。
综上:首先需匹配到一个数字,然后若该数字后有还有3个数字,则匹配到这3个数字;然后上述规则重复至少1次,直到这段字符结束。例如对1234567890的结果是234567890

例2、(?<=\s)\d+(?=\s),拆分成(?<=\s)、\d+、(?=\s)
1)(?<=\s):匹配空字符后面的位置;
2)\d+:匹配至少1个数字;
3)(?=\s):匹配空字符前面的位置;
综上:匹配两个空字符之间的数字。

例3、(?<=<(\w+)>).*(?=<\/\1>):拆分成(?<=<(\w+)>)和.*和(?=<\/\1>)
1)(?<=<(\w+)>):匹配<(\w+)>后面的位置,<(\w+)>即尖括号【<>】中包含至少1个字母;
2).*即任意数量的不包含换行的字符;
3) (?=<\/\1>):匹配<\/\1>前面的位置,<\/\1>即尖括号【<>】中包含反斜杠【即/】和组1【即前面(\w+)】的内容;
综上:匹配类似这样的一串字符balabal

十、负向零宽断言

(1)功能
【(?!exp)】:断言此位置的后面不能匹配表达式exp
【(?

(2)例子

例1、\d{3}(?!\d):匹配三位数字,而且这三位数字的后面不能是数字
     \b((?!abc)\w)+\b:匹配不包含abc的单词

例2、(?

十一、贪婪与懒惰

(1)贪婪

就是尽可能匹配满足规则的且字符最长的结果,例如:用【a.*b】来匹配aabab则匹配的结果是aabab。

(2)懒惰

就是尽可能匹配满足规则的且字符最短的结果,只需在表达式后加问号【?】即可。

例如:用【.*?】匹配aabab,会匹配aab和ab;之所以第一个匹配是aab而不是ab,简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权。

(3)其他

【*?】重复任意次,但尽可能少重复
【+?】重复1次或更多次,但尽可能少重复
【??】重复0次或1次,但尽可能少重复
【{n,m}?】重复n到m次,但尽可能少重复
【{n,}?】重复n次以上,但尽可能少重复

十二、处理选项

IgnoreCase(忽略大小写):匹配时不区分大小写。
Multiline(多行模式):更改^和$的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,$的精确含意是:匹配\n之前的位置以及字符串结束前的位置.)
Singleline(单行模式):更改.的含义,使它与每一个字符匹配(包括换行符\n)。
IgnorePatternWhitespace(忽略空白):忽略表达式中的非转义空白并启用由#标记的注释。
ExplicitCapture(显式捕获):仅捕获已被显式命名的组。

十三、平衡组/递归匹配

(1)功能
还是举例子吧,就是把最长的配对的尖括号内的内容捕获出来,其实也是说不清楚的,还是实际操作一下最好。

<                          #最外层的左括号
    [^<>]*                 #最外层的左括号后面的不是括号的内容
    (
        (
            (?'Open'<)    #碰到了左括号,在黑板上写一个"Open"
            [^<>]*        #匹配左括号后面的不是括号的内容
        )+
        (
            (?'-Open'>)    #碰到了右括号,擦掉一个"Open"
            [^<>]*         #匹配右括号后面不是括号的内容
        )+
    )*
    (?(Open)(?!))         #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败
>                         #最外层的右括号

(2)语法构造

【(?'group')】:把捕获的内容命名为group,并压入堆栈(Stack)

【(?'-group')】:从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败

【(?(group)yes|no)】:如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分

【(?!)】:零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败

(3)例子

平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配嵌套的
标签: ]*>[^<>]*(((?'Open']*>)[^<>]*)+((?'-Open'
)[^<>]*)+)*(?(Open)(?!))
.

十四、其他

【\a】:报警字符(打印它的效果是电脑嘀一声)
【\b】:通常是单词分界位置,但如果在字符类里使用代表退格
【\t】:制表符,Tab
【\r】:回车
【\v】:竖向制表符
【\f】:换页符
【\n】:换行符
【\e】:Escape
【\0nn】:ASCII代码中八进制代码为nn的字符
【\xnn】:ASCII代码中十六进制代码为nn的字符
【\unnnn】:Unicode代码中十六进制代码为nnnn的字符
【\cN】:ASCII控制字符。比如\cC代表Ctrl+C
【\A】:字符串开头(类似^,但不受处理多行选项的影响)
【\Z】字符串结尾或行尾(不受处理多行选项的影响)
【\z】:字符串结尾(类似$,但不受处理多行选项的影响)
【\G】:当前搜索的开头
【\p{name}】:Unicode中命名为name的字符类,例如\p{IsGreek}
【(?>exp) 】:贪婪子表达式
【(?-exp) 】:平衡组
【(?im-nsx:exp) 】:在子表达式exp中改变处理选项
【(?im-nsx) 】:为表达式后面的部分改变处理选项
【(?(exp)yes|no)】:把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no
【(?(exp)yes):同上,只是使用空表达式作为no
【(?(name)yes|no):如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用no
【(name)yes)】:同上,只是使用空表达式作为no

引用

【1】https://deerchao.net/tutorials/regex/regex.htm

你可能感兴趣的:(正则表达式)