正则表达式用法简介与速查

2021-07-08 16:32:10 浏览数 (1)

1. 基本元字符

元字符

说明

举例说明

.

匹配任意单个字符(换行符除外)

c.t 匹配:所有c和t之间隔一个字符的文本,如:cat, cbt, cct, …

[]

匹配字符集合中的一个字符

[abc] 匹配:a或b或c

[^]

对字符集合求非

[^abc] 匹配:“非a非b非c”的任意字符

定义一个区间

[A-Z] 匹配:字母A,B,C,…,Z中的任意一个字符

对下一个字符转义

需要转义的字符: . [ ] ^ - * ? ! { } $ ( )

2. 特殊元字符

元字符

说明

补充说明

d

匹配任意一个数字字符

等价于[0-9]

D

d 的反义,匹配一个任意非数字字符

等价于[^0-9]

w

匹配任意一个“字母数字或下划线”字符

等价于[A-Za-z0-9_]

W

w 的反义,匹配任意一个“非字母非数字非下划线”字符

等价于[^A-Za-z0-9_]

f

匹配一个换页符

(属于空白字符)

n

匹配一个换行符

(属于空白字符)

r

匹配一个回车符

(属于空白字符)

t

匹配一个制表符

(属于空白字符)

v

匹配一个垂直制表符

(属于空白字符)

[b]

匹配一个退格字符

不常用(属于空白字符)

s

匹配一个空白字符

包括上面的:f, n, r, t, v, 注意:不包括[b]

S

s 的反义,匹配任意一个非空白字符,

非 f, n, r, t, v, 的任意字符

cx

匹配一个控制字符

不常用,x为一个字母,用来表示特定的控制符。如:cM 匹配 Control-M或回车符

xn

用一个ASCII字符的十六进制值去匹配这个ASCII字符

不常用,n为十六进制数表示

n

用一个ASCII字符的八进制值去匹配这个ASCII字符

不常用,n为八进制数表示

3. 次数元字符

元字符

说明

举例说明

*

匹配前一个字符(或子表达式)的 0 次或 多次重复

cat* 匹配:ca, cat, catt, cattt, …

匹配前一个字符(或子表达式)的 1 次或 多次重复

cat 匹配:cat, catt, cattt, …

?

匹配前一个字符(或子表达式)的 0 次或 1 次重复

cat? 匹配:ca, cat

{n}

匹配前一个字符(或子表达式)的 n 次重复

cat{3} 匹配:cattttt

{n, }

匹配前一个字符(或子表达式)的至少 n 次重复

cat{3,} 匹配:cattt, catttt, cattttttt, …

{n, m}

匹配前一个字符(或子表达式)的 至少 n 次且至多 m 次重复

cat{3,5} 匹配:cattt, catttt, cattttt

*?

* 的懒惰版本

cat*? 懒惰匹配:t 的 0 次或 多次重复

?

的懒惰版本

cat ? 懒惰匹配:t 的 1 次或 多次重复

{n, }?

{n, } 的懒惰版本

cat{3,} 懒惰匹配:t 的至少 3 次重复

4. 位置元字符

元字符

说明

补充说明

b

匹配单词的边界

b 的判断依据是:位置两边分别为 w 和 W

B

b 的反义,匹配非边界

B 的判断依据是:位置两边同为 w 或同为 W

<

匹配单词的开头

(扩展的正则表达式,egrep支持)

>

匹配单词的结束

(扩展的正则表达式,egrep支持)

^

匹配字符串的开头

一般将整段文本视为一个字符串,可以和分行匹配模式组合使用

$

匹配字符串的结尾

一般将整段文本视为一个字符串,可以和分行匹配模式组合使用

A

匹配字符串的开头

同 ^,但不受分行匹配影响

z

匹配字符串的结尾

同 $,但不受分行匹配影响

(?m)

分行匹配模式

(很多正则表达式实现不支持)

5. 子表达式与回溯

元字符

说明

补充说明

()

定义一个子表达式

子表达式在一些文档中有时也称为 pattern(模式)

|

逻辑或操作

一般用在子表达式内,如:(ab|cd) 表示匹配 ab 或 cd

1

匹配第1个子表达式

1 表示左起第1个子表达式,2 表示第2个子表达式,依此类推

?(n)

条件回溯(if then)

如果第n个子表达式中的内容存在,则匹配判断条件之后的内容

?(n)|

条件回溯(if then else)

类似上面,then 要执行的内容与 else 要执行的内容之间,用 | 隔开。

6. 前后查找

元字符

说明

举例说明

(?=)

向前查找

(?=a)d 匹配:以 a 开头的数字,但 a 本身不在返回文字中

(?<=)

向后查找

(?<=a)d 匹配:以 a 结尾的数字,但 a 本身不在返回文字中

(?!)

负向前查找

向前查找的 negtive 形式,(?!a)d 匹配:不以 a 开头的数字,

(?!=)

负向后查找

向后查找的 negtive 形式,(?<!a)d 匹配:不以 a 结尾的数字,

7. 常用正则表达式示例

IP地址

(((d{1,2})|(1d{1,2})|(2[0-4]d)|(25[0-5])).){3} ((d{1,2})|(1d{1,2})|(2[0-4]d)|(25[0-5]))

Email地址

(w .)*w @(w .) [A-Za-z]

URL地址

https?://[-w.] (:d )?(/([w/_.]*)?)?

HTML注释

<!-{2,}.*?-{2,}>

Js注释

//.*

验证整数

^-?d $

验证非负整数

^d $

验证正整数

^ ?[1-9]d*$

验证浮点数

^(-?d )(.d )?$

8. Python 中使用正则表达式的方法及示例

点击标题,跳转到下文详细说明。

9. JavaScript 中使用正则表达式的方法及示例

点击标题,跳转到下文详细说明。

1. 基本元字符用法简单说明

(1) 匹配单个字符

示例文本

代码语言:javascript复制
sales1.xls, a1.txt, sales2.xls, sales3.xls, a2.xls

正则表达式

代码语言:javascript复制
sales.

匹配结果

代码语言:javascript复制
sales1.xls, a1.txt, sales2.xls, sales3.xls, a2.xls

解释:

匹配以“sales”开头,后跟任意一个字符的6字符组合。

(2) 使用转义字符

示例文本

代码语言:javascript复制
sales1.xls, a1.txt, sales2.xls, sales3.xls, a2.xls

正则表达式

代码语言:javascript复制
sales..xls

匹配结果

代码语言:javascript复制
sales1.xls, a1.txt, sales2.xls, sales3.xls, a2.xls

解释:

匹配以“sales”开头,后跟任意一个字符,再后以“.xls”结尾的10字符组合。

(3) 匹配字符中的某一个

示例文本

代码语言:javascript复制
a1.txt, b1.txt, c1.txt, d1.txt

正则表达式

代码语言:javascript复制
[ac]1

匹配结果

代码语言:javascript复制
a1.txt, b1.txt, c1.txt, d1.txt

解释:

匹配以“a”或“c”开头,后跟字符“1”的2字符组合。

(4) 特定字母可大小写

示例文本

代码语言:javascript复制
The phrase is RegEx or regex, but not regEx.

正则表达式

代码语言:javascript复制
[Rr]eg[Ee]x

匹配结果

代码语言:javascript复制
The phrase is RegEx or regex, but not regEx

解释:

匹配 regex,其中第1个字符r大小写皆可,第4个字符e大小写皆可。

(5) 定义区间匹配

用法:

[a-z]可匹配所有小写字母,[A-Z]可匹配所有大写字母,[0-9]可匹配所有数字。

注意:如果要匹配所有大小写字母,要写成:[A-Za-z],而不能写成:[A-z](因为其中会包含一些 ASCII符号)。

示例文本

代码语言:javascript复制
a1.txt, b1.txt c2.txt, d3d.txt, ee.txt

正则表达式

代码语言:javascript复制
[a-z][0-9].txt

匹配结果

代码语言:javascript复制
a1.txt, b1.txt, c2.txt, d3d.txt, ee.txt

解释:

匹配:第1个字符为小写字母,第2个字符为数字,最后以“.txt”结尾。

(6) 组合使用

示例文本

代码语言:javascript复制
background-color="#A2A2A2"; color="#000000"

正则表达式

代码语言:javascript复制
#[A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9][A-Fa-f0-9]

匹配结果

代码语言:javascript复制
background-color="#A2A2A2"; color="#000000"

解释:

对于十六进制数,每位的定义范围为0~9,A,B,C,D,E,F,在上面的正则表达式中使用[A-Fa-f0-9], 重复6次,即可得到一个6位的十六进制数的匹配。(在后面第3小节介绍完次数匹配后,本例有更为简洁的写法。)

(7) 取非匹配

示例文本

代码语言:javascript复制
a1.txt, b2.txt, C3.txt, cc.txt, dd.txt

正则表达式

代码语言:javascript复制
[a-z][^0-9].txt

匹配结果

代码语言:javascript复制
a1.txt, b2.txt, C3.txt, cc.txt, dd.txt

解释:

匹配:第1个字符为小写字母,第2个字符不是数字,最后以“.txt”结尾。

2. 特殊元字符用法简单说明

(1) 匹配换行

说明:

在Windows下,换行用 rn 表示;在Linux下,换行仅用一个 n 表示。

示例文本(Windows下文本)

代码语言:javascript复制
001, Tom,  Male
002, Tina, Female

003, Jack, Male

正则表达式

代码语言:javascript复制
rnrn

匹配结果

代码语言:javascript复制
001, Tom,  Male
002, Tina, Female 
                  
003, Jack, Male

解释:

匹配Windows下的2个换行,如果在Linux下,相同匹配的正则表达式可写成:nn

(2) 匹配数字字符

示例文本

代码语言:javascript复制
if(testArray[2] == 10) { ... }

正则表达式

代码语言:javascript复制
testArray[d]

匹配结果

代码语言:javascript复制
if(testArray[2] == 10) { ... }

解释:

对于数组外的方括号 “[” 和 “]”,要用转义字符,中间的 d 匹配单个数字字符。

(3) 匹配ASCII字符的十六进制值

示例文本

代码语言:javascript复制
ABCDEABC

正则表达式

代码语言:javascript复制
x41

匹配结果

代码语言:javascript复制
ABCDEABC

解释:

xn中的n表示ASCII字符的十六进制值,例如ASCII字符 “A” 的ASCII值写成十六进制为0x41, 则 x41 可匹配文本中的所有 “A” 字符。

3. 次数元字符用法简单说明

(1) 匹配 1 次或多次重复:

示例文本

代码语言:javascript复制
The 1st email is to tom@initcircuit.com.
The 2nd email is to jane@cnblogs.com.
The 3rd email is to tim.brown@initcircuit.com.cn.

正则表达式

代码语言:javascript复制
w @w .w 

匹配结果

代码语言:javascript复制
The 1st email is to tom@initcircuit.com.
The 2nd email is to jane@cnblogs.com.
The 3rd email is to tim.brown@initcircuit.com.cn.

解释:

w 可以有效匹配一个或多个字母数字下划线,所以能匹配出前两个email地址。 但在第3个匹配时有点问题,由于 w 不包括“.”号,所以第3个email地址的@前面和@后面都只匹配了一部分,解决方案见下条目。

(2) 匹配 0 次或多次重复: *

示例文本

代码语言:javascript复制
The 1st email is to tom@initcircuit.com.
The 2nd email is to jane@cnblogs.com.
The 3rd email is to tim.brown@initcircuit.com.cn.

正则表达式

代码语言:javascript复制
w [w.]*@[w.] .w 

匹配结果

代码语言:javascript复制
The 1st email is to tom@initcircuit.com.
The 2nd email is to jane@cnblogs.com.
The 3rd email is to tim.brown@initcircuit.com.cn.

解释:

可以把上面的正则表达式拆成5部分分别来看:w   [w.]*    @    [w.]   .w

第1部分的 w 表示必须以字母或数字开头,不能有“.”开头,这部分匹配上面的:tom, jane, tim。

第2部分的 [w.]* 表示可以有0个或多个的“字母数字”或“.”号,这部分匹配上面的:.brown。

第3部分的 @ 直接匹配文中的 @。先跳过第4部分,直接看第5部分。

第5部分的 .w 表示先匹配一个“.”号,后面再跟1个或多个的字母数字,这部分匹配上面的:.com, .com, .cn。

最后看第4部分的 [w.] ,表示可匹配一个或多个的字母数字或“.”号,这部分匹配上面的:initcircuit, cnblogs, initcircuit.com。

(3) 匹配 0 次或 1 次 重复: ?

示例文本

代码语言:javascript复制
The URL is http://www.initcircuit.com/, and  https://www.initcircuit.com/.

正则表达式

代码语言:javascript复制
https?://[w./] /

匹配结果

代码语言:javascript复制
The URL is http://www.initcircuit.com/, and  https://www.initcircuit.com/.

解释:

正则表达式中的 s? 可匹配 s 的 0 次或 1 次出现。

(4) 匹配重复的次数: {n}

示例文本

代码语言:javascript复制
background-color="#A2A2A2"; color="#000000"

正则表达式

代码语言:javascript复制
#[0-9A-Fa-f]{6}

匹配结果

代码语言:javascript复制
background-color="#A2A2A2"; color="#000000"

解释:

匹配一个十六进制位的6次重复。

(5) 匹配至少重复的次数: {n,}

示例文本

代码语言:javascript复制
001: 123.01
002: 52.48
003: 1024.56

正则表达式

代码语言:javascript复制
d : d{3,}.d{2}

匹配结果

代码语言:javascript复制
001: 123.01
002: 52.48
003: 1024.56

解释:

中间的 d{3,}. 匹配:点号前至少有3位数字, 这样就把大于100数字给匹配出来了。

(6) 匹配重复次数的区间: {n,m}

示例文本

代码语言:javascript复制
2018-01-01
99/12/01
3-3-3
03-03-03

正则表达式

代码语言:javascript复制
d{2,4}[-/]d{1,2}[-/]d{1,2}

匹配结果

代码语言:javascript复制
2018-01-01
99/12/01
3-3-3
03-03-03

解释:

本例用于匹配合法的日期,最前面的d{2,4}用于匹配年份, 用2位数或4位数表示年份都可以,中间的 [-/] 表示日期分隔符,“-”或“/”都可以匹配(其中“-”前用了转义符), 后面的 d{1,2} 表示月份,用1位或2位都可以匹配出来。(本例只是展示 {n,m} 的用法,匹配表达式写法并不完美, 后面有匹配日期更好的正则表达式的写法)

(7) 防止过度匹配,懒惰型次数匹配符: *?,   ?,   {n,}?

示例文本

代码语言:javascript复制
The html is <p>abc</p> and <p>def</p>.

正则表达式

代码语言:javascript复制
<p>.*</p>

匹配结果

代码语言:javascript复制
The html is <p>abc<p> and <p>def<p>.

解释:

由于正则表达式中间的.*可匹配任意字符的任意多次重复, 因此把本行的最前面1个<p>和最后的一个</p>中间的内容都一股脑儿地全都匹配了出来, 这不是我们想要的结果。可使用 * 的懒惰型版本 *? 来匹配,改进如下:

正则表达式

代码语言:javascript复制
<p>.*?</p>

匹配结果

代码语言:javascript复制
The html is <p>abc<p> and <p>def<p>.

解释:

懒惰型版本 *? 在匹配任意次数的重复的字符时,会时时注意其后面的表达式 </p>,如果一旦发现后面的表达式</p>符合匹配条件,自己本身就停止继续匹配了。所以在本例中, 只匹配到</p>之前的部分。

4. 位置元字符用法简单说明

(1) 匹配单词边界

示例文本

代码语言:javascript复制
There is a car on the card.

正则表达式

代码语言:javascript复制
car

匹配结果

代码语言:javascript复制
There is a car on the card.

解释:

我们只想匹配 car,不想匹配后面的 card, 此时需要使用单词边界匹配 b,改进如下:

正则表达式

代码语言:javascript复制
bcarb

匹配结果

代码语言:javascript复制
There is a car on the card.

解释:

单词边界匹配符 b 判断单词边界的依据是: 它的左右两边分别是一个 w 和 一个 W。注意:位置元字符 b 仅匹配位置,其本身并不匹配任何实际出现的字符。 在本例中,car 单词的开头处,其左边是一个空格(即W),右边是一个字母 c(即w),符合 b 的边界判断条件。car 单词的结尾也类似,car 单词结尾处,其左边是一个字母 r(即w),右边是一个空格(即W),亦符合 b 的边界判断条件, 故2个 b 的中间不分的 car 被匹配出来。

(2) 匹配字符串开头与结尾

示例文本

代码语言:javascript复制
something
<html>
    blablabla
</html>
something else

正则表达式

代码语言:javascript复制
<html>.*</html>

匹配结果

代码语言:javascript复制
something
<html>
    blablabla
</html>
something else

解释:

如果我们希望,整段文本只有当以<html>开头时才匹配, 若之前有其他内容则不匹配;同样,整段文本只有以</html>结尾时才匹配,之后若有其他内容则不匹配, 此时就需要用到 ^(字符串开头)和 $(字符串结尾)匹配符了。改进如下:

正则表达式

代码语言:javascript复制
^<html>.*</html>$

匹配结果

代码语言:javascript复制
something
<html>
    blablabla
</html>
something else

解释:

这样,上面的示例文本就不会有内容被匹配出来了。

5. 子表达式与回溯用法简单说明

(1) 子表达式

说明:

前面的“次数元字符”只能匹配1个字符的若干次重复, 如果我们要匹配一个字符串的若干次重复,就需要用到子表达式。

示例文本

代码语言:javascript复制
The abcabc can match, but not the abc.

正则表达式

代码语言:javascript复制
(abc){2}

匹配结果

代码语言:javascript复制
The abcabc can match, but not the abc.

解释:

子表达式(abc)重复2次可以被匹配出来。

(2) 匹配IP地址

示例文本

代码语言:javascript复制
The IP address is 192.168.1.10.

正则表达式

代码语言:javascript复制
(d{1,3}.){3}d{1,3}

匹配结果

代码语言:javascript复制
The IP address is 192.168.1.10.

解释:

子表达式为(d{1,3}.),表示1~3位数字后跟一个“.”号, 可以匹配形如:“192.”或“1.”这样的字符模式。之后的 {3} 表示重复3次,即可以把“192.168.1.”匹配出来了。 最后的 d{1,3} 表示1~3位数字,可以把最后的“.10”匹配出来。当然,这个正则表达式并不完美, 会把超过255的不合理的IP地址也匹配出来,后面的“常用正则表达式示例”会有更好的解决方案。

(3) 逻辑或的使用

示例文本

代码语言:javascript复制
1111, 1920, 5279, 2099, 199

正则表达式

代码语言:javascript复制
(19|20)d{2}

匹配结果

代码语言:javascript复制
1111, 1920, 5279, 2099, 199

解释:

这里只匹配以19或20开始的年份,子表达式中使用了“|”号, 匹配19或20,后面的 d{2} 表示后面再跟2位数字。

(4) 子表达式的嵌套

说明:

这里我们用子表达式的嵌套来解决前面的IP地址的合理性问题。 我们要找到255及以下的数字,有4种合理情况:(1) 1位或2位数字;(2) 以1开头的3位数字; (3) 以2开头的3位数字,十位为0~4的;(4) 以25开头的3位数字,个位为0~5的。

示例文本

代码语言:javascript复制
192. 255. 10. 999. 

正则表达式

代码语言:javascript复制
b((d{1,2})|(1d{1,2})|(2[0-4]d)|(25[0-5])).

匹配结果

代码语言:javascript复制
192. 255. 10. 999.

解释:

这个嵌套的正则表达式看上去很复杂,其实拆开来看还是比较简单的:

b( (d{1,2}) | (1d{1,2}) | (2[0-4]d) | (25[0-5]) ).

其中,4个黑色文字的子表达式分别表示前述4种情况的匹配, 它们之间用逻辑或并列嵌入到外层的一个子表达式中(红色括号),最前面的 b 匹配单词边界, 最后的 . 匹配点号。

(5) 回溯引用

说明:

有时我们想匹配文本中连续出现的2个重复单词,而不管单词内容是什么, 这种需求只能用子表达式的回溯引用来实现。在回溯引用时,若正则表达式中有若干个子表达式, 则 1 表示从左数起第1个子表达式,2 表示第2个子表达式,依此类推。 在许多实现里, 可用来代表整个正则表达式。

示例文本

代码语言:javascript复制
There is a white white cat.
The color of of the dog yellow.

正则表达式

代码语言:javascript复制
b(w )b[ ] 1

匹配结果

代码语言:javascript复制
There is a white white cat.
The color of of the dog yellow.

解释:

正则表达式中,b(w )b 表示匹配1个单词, [ ] 表示匹配其后的1个或多个空格,最后的 1 就是回溯引用前面的子表达式 (w ) 中匹配的内容, 若 (w ) 匹配到 white,则 1 也去匹配 white;若 (w ) 匹配到 of,则 1 也去匹配 of。

(6) 利用回溯匹配html配对标签

示例文本

代码语言:javascript复制
<h1>This line is right.</h1>
<h2>This line is also right.</h2>
<h1>Wrong!!!</h2>

正则表达式

代码语言:javascript复制
<h([1-6])>.*?</h1>

匹配结果

代码语言:javascript复制
<h1>This line is right.</h1>
<h2>This line is also right.</h2>
<h1>Wrong!!!</h2>

解释:

对于<h>标签,其中数字只能配对出现, 故使用回溯子表达式,1 表示前面子表达式 ([1-6]) 已匹配到的数字。另外,注意这里使用了 *? 懒惰型次数匹配符。

(7) 条件回溯

说明:

有时我们有这种需求,比如在 html 文件中, 我们想要匹配所有被<span>…</span>包裹的标签。但如果这个<span>被包裹在 <p>…</p>中,则把外层的<p>和</p>标签中的内容也一起匹配出来。

示例文本

代码语言:javascript复制
<body>
<span>something</span>
<p><span>anything</span></p>
<p class="abc"><span>everything</span></p>
</body>

正则表达式

代码语言:javascript复制
(<ps*[^>]*>s*)?<span>.*?</span>(?(1)s*</p>)

匹配结果

代码语言:javascript复制
<body>
<span>something</span>
<p><span>anything</span></p>
<p class="abc"><span>everything</span></p>
</body>

解释:

这个正则表达式比较长,需要拆解开来分析:

(<ps*[^>]*>s*)? <span>.*?</span> (?(1)s*</p>)

先看黑体显示的第1个子表达式,这可以匹配: <p>或<p class=”abc”>,其后的 ? 表示 0 次或 1 次匹配,即<p>标签可以出现1次,也可以没有。

其后的 <span>.*?</span> 部分比较简单, 可匹配<span>标签对及其中的文字内容,注意这里用了懒惰型元字符 *? 匹配 0 个或多个字符。

最后是红色括号中的条件回溯,红字表示,若第1个子表达式有匹配, 则执行匹配后面的 s*</p>部分,若第1个子表达式没有出现匹配,则后面的 s*</p>也不作匹配。

6. 前后查找元字符用法简单说明

(1) 向前查找(lookahead)

说明:

有时我们想匹配某种模式之前的内容, 但又不想把这个模式本身给匹配出来,这时可用到前向查找。如下例中,我们想匹配冒号前的字符, 但又不想把冒号本身给匹配出来。

示例文本

代码语言:javascript复制
http://www.initcircuit.com/
https://www.initcircuit.com/

正则表达式

代码语言:javascript复制
. (?=:)

匹配结果

代码语言:javascript复制
http://www.initcircuit.com/
https://www.initcircuit.com/

解释:

正则表达式中,. 表示匹配1个或多个任意字符,(?=:)为匹配冒号, 但匹配结果仅为冒号前的字符(不包含冒号),这就是“向前查找”的含义。

(2) 术语:消费(consume)

说明:

有些正则表达式文档会使用“消费”(consume)这一术语, 表示“匹配且返回文本”的含义。在上面的向前查找(lookahead)中的例子中,冒号被匹配但不在返回文本中, 故称为:不消费。

(3) 向后查找(lookbehind)

示例文本

代码语言:javascript复制
Tom: 80
Jane: 95
Jack: 100

正则表达式

代码语言:javascript复制
(?<=:s*)d 

匹配结果

代码语言:javascript复制
Tom: 80
Jane: 95
Jack: 100

解释:

本例中,需要匹配冒号后的数字,所以用到了向后查找 (?<=) 元操作符,由于冒号后还有若干个空格, 故用 s* 予以匹配,但冒号和空格都不出现在匹配结果中, 只出现后面 d 匹配的数字

(4) 取反前后查找(negtive lookahead/lookbehind)

说明:

在下面的例子中,要匹配a开头的数字(但只取出数字)很容易, 只要使用普通的“向后查找”就可以了。但是如果要匹配那些不以a开头的纯数字(如下例中的80和95), 就需要用到“取反前后查找”了。

示例文本

代码语言:javascript复制
Tom's cardnum is a01. His score is 80. Jane's cardnum is a02. Her score is 95.

正则表达式

代码语言:javascript复制
b(?<!a)d b

匹配结果

代码语言:javascript复制
Tom's cardnum is a01. His score is 80. Jane's cardnum is a02. Her score is 95.

解释:

这里的 (?<!a) 就是取反向后查找, 把不是以 a 开头的数字给匹配出来。注意前后使用的 b 单词边界,如果不用 b 会把文中的 1 和 2 也匹配出来。

8. Python 中使用正则表达式的方法及示例

(1) 概述

Python使用正则表达式需要导入 re 模块,可以直接调用 re的成员函数于对字符串进行正则表达式匹配,也可以通过把正则表达式先编译成一个“正则表达式对象”, 然后使用这个对象进行操作和匹配。这里仅介绍第一种方法。

(2) re 的部分常用函数

findall(pattern, string [,flags])

在 string 中匹配 pattern,匹配结果用一列表返回

finditer(pattern, string [,flags])

同上,但返回一个迭代器

split(pattern, string [,maxsplit = 0])

根据 pattern 出现的位置拆分 string,返回字符串列表,参数 maxsplit 为最大拆分次数,默认全部拆分。

sub(pattern, repl, string [,count = 0])

使用 repl 替换 string 中出现的 pattern,返回替换后的新字符串。参数 count 为最大替换次数,默认全部替换。

subn(pattern, repl, string [,count = 0])

同上,但返回一个元组,其中包含新字符串和替换次数

compile(str [,flags])

编译正则表达式对象,这里暂不介绍

(3) 示例一(将日期匹配出来)

python代码

代码语言:javascript复制
import re
text = 'The test date is from 2018/1/1 – 2018/12/31'
patt = '(d{4})/(d{1,2})/(d{1,2})'
re.findall(text, patt)

执行结果

代码语言:javascript复制
[('2018', '1', '1'), ('2018', '12', '31')]

解释:

执行结果为 re.findall 函数返回的匹配结果列表。 由于正则表达式中使用了3个子表达式,故在结果中,把这3个子表达式的匹配结果分开放到了一个元组中。

(4) 示例二:将日期格式替换成欧洲格式(即:日/月/年)

python代码

代码语言:javascript复制
import re
text = 'The test date is from 2018/1/1 – 2018/12/31'
patt = '(d{4})/(d{1,2})/(d{1,2})'
re.sub(patt, r'321', text)

执行结果

代码语言:javascript复制
The test date is from 1/1/2018 - 31/12/2018

解释:

执行结果为 sub.re 函数返回的结果,其中 repl 用到了正则表达式中的子表达式回溯引用表示。

9. JavaScript 中使用正则表达式的方法及示例

(1) 概述

在Js中,可以通过 String 对象和 RegEx 对象实现正则表达式处理, 这里仅介绍 String 对象的方法。注意在Js中,正则表达式首尾用两个“/”来括起, 这样可自动生成一个正则表达式对象,而不是双引号或单引号(用引号的话,就是字符串对象了)。

(2) String 对象中关于正则表达式的函数

str.search(regexp)

在 String 对象中查找匹配入参正则表达式 regexp,匹配成功则返回在字符串中首次匹配项的索引; 否则返回 -1

str.match(regexp)

在 String 对象中查找匹配正则表达式 regexp,匹配成功则返回一个包含若干匹配信息的 Array(内容详见下例二), 未匹配则返回 null

str.replace(regexp|substr, newSubStr)

将 String 对象内匹配到的 regexp 替换成 newSubStr,返回新字符串,原字符串不变。

str.split(regexp [,limit])

使用regexp描述的分隔符将一个 String 对象分割成字符串数组。

(3) 示例一(search使用)

Js代码

代码语言:javascript复制
var text = 'The fox, and the dog.';  // 生成1个String对象
var regex = /[^ws]/;              // 匹配非字母和非空格
var idx = text.search(regex);
console.log(idx);
console.log(text[idx])

执行结果

代码语言:javascript复制
> 7
> ","

解释:

search 匹配到的第一个非字母和非空格是“,”, 故返回其索引值:7。

(4) 示例二(match使用)

Js代码

代码语言:javascript复制
var text = 'For more information, see Chapter 3.4.5.1';  
var regex = /see (Chapter d (.d)*)/;      // 不使用 g 标志
var ary = text.match(regex);
console.log(ary);

执行结果

代码语言:javascript复制
> ["see Chapter 3.4.5.1", 
"Chapter 3.4.5.1", 
".1"
index: 22,
input: 'For more information, see Chapter 3.4.5.1']

解释:

可以看到返回 Array 中,各个子表达式的匹配。

Js代码(regexp使用 g 标志)

代码语言:javascript复制
var text = 'For more information, see Chapter 3.4.5.1';  
var regex = /see (Chapter d (.d)*)/g;      // 使用 g 标志
var ary = text.match(regex);
console.log(ary);

执行结果

代码语言:javascript复制
> ["see Chapter 3.4.5.1"]

解释:

使用 g 标志后,仅将整体匹配结果放入返回 Array 中。

(5) 示例三(replace使用)

Js代码

代码语言:javascript复制
var text = 'The fox, and the dog.';   
var regex = /dog/;               
var newtext = text.replace(regex, 'cat');
console.log(newtext);

执行结果

代码语言:javascript复制
> The fox, and the cat.

解释:

replace 匹配到 dog 后,用 cat 替换。 新字符串通过返回值返回,原字符串不变。

转载于:https://www.cnblogs.com/initcircuit/p/10754680.html

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100956.html原文链接:https://javaforall.cn

0 人点赞