正则表达式的那点事儿

       在编程中,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。然而正则表达式的语法很令人头疼,即使对于经常使用它的人来说也是如此。下面我将简单介绍一下正则表达式,帮助大家快速入门。文中内容如有不妥之处,欢迎大家提出宝贵意见。

一、元字符(metacharacter)

 

表1 常用的元字符

符号说明
.

匹配除换行符以外的任意字符

\w

匹配字母、数字、下划线、汉字

\s

匹配任意的空白符,包括:空格、制表符(Tab)、换行符、中文全角空格等

\d

匹配一位数字

\b

匹配单词的开始或结束,也就是单词的分界处

^

匹配字符串的开始

$

匹配字符串的结束


例子:

10\d{5}-\d{8}

匹配以0为开头,然后是5个数字,然后是一个连字符“-”最后匹配8个数字。

2\ba\w*\b

   匹配以字母a开头的单词,然后是任意数量的字母、数字、下划线或汉字。

3\d+

匹配1个或更多连续的数字。

4\b\w{5}\b

匹配5个字符的单词。

注意:

       元字符^$都匹配一个位置,这和\b有点类似。^匹配你要用来查找的字符串的开头,$匹配结尾。例如一个网站如果要求你填写的密码必须为6位到12位字符时,可以使用:^\d{6,12}$

二、字符转义

       为什么会有转义字符呢?如果你想查找某些特殊含义的字符,比如说元字符本身,这个时候直接查找是不合适的,因为元字符会被解释成别的意思,这个时候就会用到转义字符\)。例如:C:\\Users匹配C:\Users

三、限定符

 

表2 常用的限定符

符号说明

*

重复零次或更多次

+

重复一次或更多次

重复零次或一次

{n}

重复n

{n,}

重复n次或更多次

{n,m}

重复nm


例子:

1user\d*

   匹配user后面跟零个或更多个数字

四、字符类

 

表3 常用的字符匹配

符号说明

[abc]

匹配字母abc

[.?!]

匹配标点符号.?!

[a-z0-9A-Z]

匹配一个英文字母或数字

[0-9]

匹配任意一个数字,相当于\d


例子:

1\(?0\d{2}[) -]?\d{8}

   匹配0个或1(,然后是匹配一个0,后面匹配两个数字,然后是匹配)或空格或-中的0个或1个,最后匹配8个数字。

五、分支条件

        正则表达式里的分支条件是指有很多种规则,如果满足其中的一种规则就应该予以匹配。分支条件的符号是|,用|将不同的规则分隔开来。


例子:

1\(?0\d{2}\)?[- ]?\d{8}|0\d{2}[- ]?\d{8}

该正则表达式可以匹配两种类型的字符串:第一,匹配0个或1(,后面匹配一个0,接着匹配两个数字,然后匹配0个或1),后面匹配-或空格0个或者1个,最后匹配8个数字;第二,匹配一个数字0,然后匹配两个数字,接着匹配-或空格的0个或1个,最后匹配8个数字。

注意:

       使用分支条件时,要注意各个条件的顺序。因为匹配分支条件时,将会从左到右的测试每一个条件,如果满足了某个分支的话,就不会再去管其他的条件了。

六、分组

       当需要重复多个字符时,就会用到分组。将需要重复的多个字符用小括号括起来构成一个子表达式,这个子表达式就是分组。将这个子表达式看成一个整体,然后就可以指定这个子表达式的重复次数了。


例子:

1)匹配一个IP地址:

((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?),这是一个子表达式。这个子表达式里面又有两个分支条件。先来看第一个分支条件,首先匹配一个数字2,然后匹配数字0-4中的任意一个,最后匹配任意一个数字。再来看第二个分支条件,首先匹配数字25,然后匹配0-5中的任意一个数字。最后看第三个分支条件,首先,匹配数字01中的0个或1个,然后,匹配一个任意的数字,最后匹配一个任意的数字。

   第一个子表达式匹配完成之后,会匹配一个.((2[0-4]\d|25[0-5]|[01]?\d\d?)\.)匹配完成之后,会作为一个分组继续匹配后面的语句,即重复这个分组3次。最后继续匹配后面的语句,后面的语句与第一个子表达式里面的语句相似,在此就不赘述了。

七、反义

       如果想要查找除了小写字母之外,其他任何字符都行的情况。这个时候,用反义是比较方便的,下面是一些常用的反义代码。


表4 常用的反义符

符号说明

\W

匹配任意不是字母,数字,下划线,汉字的的字符

\S

匹配任意不是空白符的字符

\D

匹配任意非数字的字符

\B

匹配不是单词开头或结束的位置

[^a]

匹配除了a以外的任意字符



例子:

1)\D+

匹配不包含数字的字符串

2x[^a]+

匹配以x开头不包含a的字符串

八、后向引用

       后向引用用于重复搜索前面某个分组匹配的文本,每个分组都会拥有一个组号,组号的命名规则是:从左向右,以左括号为标志,按照出现的顺序命名12...。下面以一个例子具体展开说明。

       \b(\w+)\b\s+\1\b的匹配原则是:首先匹配一个单词,然后是一个或多个空白符,最后是分组一中的内容。所以说,这个正则表达式最终可以匹配重复的单词,比如like like

        组名也可以自己设定,可以使用(?<xzw>\w+)(?'xzw'\w+)来把上例的组名更改为xzw。

九、零宽断言

       零宽断言是用来查找某些内容之前或之后(不包含内容本身)的东西的,即零宽断言是用于指定一个位置的,下面是常用的四种零宽断言。


表5 常见的4种零宽断言

符号说明

(?=exp)

零宽度正预测先行断言,它断言自身出现的位置的前面能匹配表达式exp

(?<=exp)

零宽度正回顾后发断言,它断言自身出现的位置的后面能匹配表达式exp

(?!exp)

零宽度负预测先行断言,断言此位置的后面不能匹配表达式exp

(?<!exp)

零宽度负回顾后发断言,断言此位置的前面不能匹配表达式exp


十、懒惰匹配

        所谓懒惰匹配就是指匹配尽可能少的字符,下面给出几个常用的懒惰限定符。


表6 常用的懒惰限定符

符号说明

*?

重复任意次,但尽可能少重复

+?

重复1次或更多次,但尽可能少重复

??

重复0次或1次,但尽可能少重复

{n,m}?

重复nm次,但尽可能少重复

{n,}?

重复n次以上,但尽可能少重复


十一、补充内容


表7 常用分组语法


表8  其他符号 

符号说明

\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的字符类

(?>exp)

贪婪子表达式

(?<x>-<y>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


       好了。至此就是本文的所有内容了,相信大家现在对正则表达式已经有了一定的了解了吧。  

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

象在舞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值