初识正则表达式

来源:互联网 发布:js如何获取classname 编辑:程序博客网 时间:2024/05/17 04:08

初识正则表达式

这里写图片描述


这里写图片描述


这里写图片描述


这里写图片描述


这里写图片描述


这里写图片描述


正则表达式测试器下载:

软件下载 中文版

英文版

英文版界面
这里写图片描述

中文版界面

这里写图片描述

参考文档


这里写图片描述


匹配出文本的 w
这里写图片描述


原样匹配
这里写图片描述


这里写图片描述
这里写图片描述


匹配数字

这里写图片描述


匹配非数字

这里写图片描述


匹配任意单字符

这里写图片描述


匹配非单字符

这里写图片描述


匹配空白字符(空格)

这里写图片描述


匹配非空格

这里写图片描述


匹配任意字符

这里写图片描述


匹配括号中的任意字符

这里写图片描述


匹配字符串的开始与行数

这里写图片描述


匹配字符串结尾行数

这里写图片描述


匹配一个单词的边界

这里写图片描述


匹配一个单词的非边界

这里写图片描述


转义字符匹配

这里写图片描述


匹配小圆点必须通过\转义

这里写图片描述


这里写图片描述


限定字符

这里写图片描述


这里写图片描述


匹配N次字符

这里写图片描述


这里写图片描述


匹配N次和N次以上字符
这里写图片描述


匹配n次以上m次以下字符

这里写图片描述


匹配0次或1次

这里写图片描述


匹配一次或多次

这里写图片描述


匹配0次以上

这里写图片描述


匹配非括号字符

这里写图片描述


分组

这里写图片描述


匹配IP地址(192.168.1.1)

这里写图片描述


这里写图片描述


这里写图片描述


加上开始与结尾符
这里写图片描述


删除空行 并替换空格内容

这里写图片描述


实例匹配qq号

5位到9位的号码 第一位不是0

这里写图片描述


实例匹配邮箱

这里写图片描述


汉字匹配 (\u表示16进制)

这里写图片描述


\b\b与^$的分别用法

这俩个用法比较容易混淆
\b\b的用法例如匹配qq 可以匹配每一行的qq号码 区分边界
这里写图片描述
而^&开始与结束匹配的是一行只能有一个符合的qq号码

这里写图片描述


{N}次匹配避免那么多烦人的重复

这里写图片描述
避免烦人的重复

这里写图片描述
加上开始与结束 轻松匹配
这里写图片描述


这里写图片描述


常用元字符综合使用

这里写图片描述


匹配刚好6个字符的单词

这里写图片描述


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

这里写图片描述


匹配以字母a开头的单词

这里写图片描述


字符类

要想查找数字,字母或数字,空白是很简单的,因为已经有了对应这些字符集合的元字符,
很简单,你只需要在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)。
这里写图片描述


首先是一个转义字符(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。
这里写图片描述


这里写图片描述


分支条件

不幸的是,刚才那个表达式也能匹配010)12345678或(022-87654321这样的“不正确”的格式。
要解决这个问题,我们需要用到分枝条件。正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。听不明白?没关系,看例子:
0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。
这里写图片描述


(?0\d{2})?[- ]?\d{8}|0\d{2}[- ]?\d{8}这个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔。你可以试试用分枝条件把这个表达式扩展成也支持4位区号的。
这里写图片描述


\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。
这里写图片描述

如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。

这里写图片描述


分组

这里写图片描述


我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作(后面会有介绍)。
(\d{1,3}.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。

这里写图片描述


如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的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?,这里我就不细说了,你自己应该能分析得出来它的意义。


反义

有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:

这里写图片描述


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

这里写图片描述


[^x] 匹配除了x以外的任意字符

这里写图片描述


**[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

这里写图片描述


后向引用

这里写图片描述


使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。难以理解?请看示例:

这里写图片描述

\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。


你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?\w+)(或者把尖括号换成’也行:(?’Word’\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k,所以上一个例子也可以写成这样:\b(?\w+)\b\s+\k\b

这里写图片描述


这里写图片描述


零宽断言

这里写图片描述


接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。最好还是拿例子来说明吧:
断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I’m singing while you’re dancing.时,它会匹配sing和danc。

这里写图片描述


(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

这里写图片描述


这里写图片描述


假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\d)\d{3})+\b,用它对1234567890进行查找时结果是234567890

这里写图片描述


下面这个例子同时使用了这两种断言:(?<=\s)\d+(?=\s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)。

这里写图片描述


负向零宽断言

前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词–它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:
\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting

这里写图片描述


负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u)\w*\b

这里写图片描述


零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;
这里写图片描述


\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。

这里写图片描述


同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。

这里写图片描述


一个更复杂的例子:(?<=<(\w+)>).(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。(?<=<(\w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是),然后是.(任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是的话,后缀就是了。整个表达式匹配的是之间的内容(再次提醒,不包括前缀和后缀本身)。

这里写图片描述


这里写图片描述


注释

小括号的另一种用途是通过语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|250-5|[01]?\d\d?(?#0-199)。
要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如,我们可以前面的一个表达式写成这样:
这里写图片描述


这里写图片描述


贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。


这里写图片描述


a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)
这里写图片描述


这里写图片描述


这里写图片描述


处理选项

上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项:

这里写图片描述


这里写图片描述


这里写图片描述


原创粉丝点击