这里发现
一只程序猿O(∩_∩)O
渴望用Hello World改变世界,喜欢电影,喜欢跑步,略带文艺的逗比程序猿一只!

正则表达式学习整理

正则表达式(Regular Expression, Regex)是一些用来匹配和处理文本的字符串,主要用来解决搜索和替换两个问题。

元字符列表:

字符 描述
. 匹配任何一个单个的字符,字母、数字或者是.字符本身
[] 可以定义一个字符集合,字符集合的匹配结果是能够与该集合里的任意一个成员相匹配的文本。
(连字符)[0-9]、[A-Z]、[0-9A-Z]字符区间
^ 对一个字符集进行取非匹配,例如[^0-9]是排除0-9的所有字符,^的效果是作用于给定字符集合里的所有字符或字符区间,而不是仅限于紧跟在^字符后面的哪一个字符或字符区间。
\ 转义字符
x|y 匹配x或y
[\b] 回退(并删除)一个字符(Backspace键)
\f 换页符
\n 换行符
\r 回车符
\t 制表符(Tab键)
\v 垂直制表符
\r\n 是Windows所使用的文本行结束标签,Unix和Linux系统只使用一个换行符来结束一个文本行,即\n;
\d 任何一个数字字符,等价于[0-9]
\D 任何一个非数字字符,等价于[^0-9]
\w 任何一个字母数字字符(大小写均可)或下划线字符,等价于[0-9A-Za-z_]
\W 非\w,等价于[^0-9A-Za-z_]
\s 任何一个空白字符,等价于[\f\n\r\t\v],注意不包括[\b]
\S 任何一个非空白字符,等价于[^\f\n\r\t\v]
+ 匹配一个或多个字符,如[0-9]+、\w+(懒惰型+?)
* 匹配零个或多个字符(懒惰型*?)
? 匹配零个或一个字符
{} 为重复数字设定一个精确的值({3})或区间{2,4}或至少多少次{3,}(懒惰型{3,}?)
\b 用来匹配一个单词的开始或结尾,其实\b匹配的是一个能够构成单词的字符(即\w)和一个不能构成单词的字符(即\W)之间
\B 非字符边界
^ 字符串开头,注意区分之前的“求非”元字符,只有在[]中才是“求非”的作用。
$ 字符串结尾
(?m) 开启分行匹配模式,但是有很多正则表达式实现不支持。

使用POSIX字符类

POSIX字符类是许多(但不是所有,如Javascript不支持)正则表达式实现都支持的一种简写形式。

[:alnum:] 任何一个字母或数字
[:alpha:] 任何一个字母
[:blank:] 空格或制表符
[:cntrl:] ASCII控制字符(ASCII 0到31,再加上ASCII 127)
[:digit:] 任何一个数字
[:print:] 任何一个可打印字符
[:graph:] 同[:print:],但不包括空格
[:lower:] 任何一个小写字母
[:upper:] 任何一个大写字母
[:punct:] 既不属于[:alnum:]也不属于[:cntrl:]的任何一个字符
[:space:] 任何一个空白字符,包括空格
[:xdigit:] 任何一个十六进制数字,等价于[a-fA-F0-9]

重复匹配(限定符):

通过前面的知识,我们知道如何匹配单个字符,但是,多数情况下我们需要匹配多个连续重复出现的字符或字符集合,比如一个单词,一组数字。一个单词由若干字母组成,一组数字由若干单数组成。这时候我们可以利用下面的一组限定符来匹配,限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。

+ 匹配一个或多个字符,如[0-9]+、\w+(懒惰型+?),等价于{1,}
* 匹配零个或多个字符(懒惰型*?)等价于{0,}
? 匹配零个或一个字符,等价于{0,1}
{} {}有三种用法,分别是:1)为重复数字设定一个精确的值,如({3});2) 设定一个区间,如{2,4}; 3) 至少多少次,如{3,}(懒惰型{3,}?)

注:*、+和{}限定符都是贪婪的,默认会尽可能多的匹配文字,在它们的后面加上一个?就可以变成懒惰型,实现最小匹配。

位置匹配(定位符):

在某些场景下,我们只需要对某段文本的特定位置进行匹配,这就是位置匹配的概念,要用到正则表单式中的定位符。

\b 用来匹配一个单词的开始或结尾,其实\b匹配的是一个能够构成单词的字符(即\w)和一个不能构成单词的字符(即\W)之间
\B 非字符边界
^ 字符串开头,注意区分之前的“求非”元字符,只有在[]中才是“求非”的作用。
$ 字符串结尾
(?m) 启用分行匹配模式

分行匹配模式:有许多正则表达式都支持使用一些特殊的元字符去改变另外一些元字符的行为,(?m)用来启用分行匹配模式。分行匹配模式使得正则表达式引擎把行分隔符当作一个子串分隔符来对待。在分行匹配模式中,^不仅匹配正常的字符串开头,还将匹配行分隔符后面的开始位置;同样地,$不仅匹配正常的字符串结尾,还将匹配行分隔符后面的结束位置。(?m)要出现在整个模式的最前面。如:

(?m)^\s*//.*$

可以把一段代码中用//注释的内容全部找出来。

但是有很多正则表达式实现不支持(?m)。

子表达式:

子表达式是一个大的表达式的一部分,把一个表达式划分为一系列子表达式的目的是为了把那些子表达式当作一个独立元素来使用。子表达式要用()括起来,比如:

( ){2,}
(\d{1,3}\.){3}\d{1,3}

子表达式还可以多重嵌套。子表达式的另一个重要用途是可以实现回溯引用。

回溯引用(反向引用):

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,就是上面描述的子表达式,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。可以理解为变量。每个缓冲区都可以使用 \1、\2、\3、……、\99等来匹配表达式中的第1,2,3,……,99个子表达式访问,在很多实现里\0可以代表整个正则表达式

回溯引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻字符串的匹配项的能力。比如下面的例子:

This is a block of  of text, several words here are are repeated, and and they should not be.

正则表达式:

[ ]+(\w+)[ ]+\1

结果:

This is a block of  of text, several words here are are repeated, and and they should not be.

分析:[ ]+匹配一个或多个空格,\w+匹配一个或多个字母数字字符,[ ]+匹配随后的空格,\1就是一个回溯引用,引用的就是前面子表达式匹配到的单词。

回溯引用还被经常用于HTML的标签匹配、URL的分解以及替换操作中。

有些正则表达式允许使用下面中的元字符进行大小写转换:

\E 结束\L或\U转换。
\l 把下一个字符转换为小写。
\L 把\L到\E之间的字符全部转换为小写。
\u 把下一个字符转换为大写。
\U 把\U到\E之间的字符全部转换为大写。

例如要把下面的HTML中一级标题的文字转为大写:

<BODY>
<H1>Welcome to my HomePage</H1>
Content is divided into two sections:<BR>
</BODY>

正则表达式:

(<[Hh]1>)(.*?)(</[Hh]1>)

替换:

$1\U$2\E$3

结果:

<BODY>
<H1>WELCOME TO MY HOMEPAGE</H1>
Content is divided into two sections:<BR>
</BODY>

前后查找:

还是上面的例子,假如我们要获取到H1中的内容,而不包括<H1>标签,我们该如何做,办法之一是用子表达式,就是上面的例子,$2就是我们需要的内容;但是,明知道<H1>是无意义的,我们就没必要检索出来,这时候该如何去做呢?这就用到了前后查找。

下面转载了一篇博文对向前向后查找的总结。

1. 向前查找:根据要匹配的字符序列<strong>后面</strong>存在一个特定的字符序列(肯定式向前查找)或不存在一个特定的序列(否定式向前查找)来决定是否匹配。对于向前查找,出现在指定项之后的字符序列不会被正则表达式引擎返回。

2. 向后查找:一个要匹配的字符序列<strong>前面</strong>有或者没有指定的字符序列

(?:…) 非捕获组
(?=…) 肯定式向前查找
(?!…) 否定式向前查找
(?<=…) 肯定式向后查找
(?<!…) 否定式向后查找

示例:

a)肯定式向前查找

eg1. 匹配字符序列Start后跟一个空格和Traing字符序列

Start(?= Traing)

eg2. 匹配字符序列sentence,如果在同一句子中还存在字符序列sequence

sentence(?=.*sequence.*)

b)否定式向前查找

eg1. 匹配字符序列Start后面不存在Traing字符序列

Start(?!\bTraing\b)

c)肯定式向后查找

eg.匹配前面有”Dr. “或”Mr “的字符序列Tian

((?<=Dr. )|(?&lt;=Mr ))Tian

d)否定式向后查找

eg.匹配前面没有”Dr. “的字符序列Tian

(?<!Dr. ) Tian

e)前后查找配合使用

eg.为>1000的数每三位添加一个逗号(1234→1,234)

(?<=\d)(?=(\d{3})+\b)

该模式表示:查找这样一个位置,改位置的前面有一个数字,且后面有一个或多个3个数字组成的字符序列,最后各一个单词结束符。

PS:最近才发现,原来&nbsp;是非换行型空格(non-breaking space)的意思,哈哈哈!

近期再整理一下不同语言或应用中正则表达式的不同点,其实正则表达式看起来复杂,实际上没多少东西。

正则表达式

正则表达式

转载请注明出处fullstackdevel.com:SEAN是一只程序猿 » 正则表达式学习整理

分享到:更多 ()

Comment 2

评论前必须登录!

  1. #1

    逗比你好,linux中的ere bre恶心。。。

    光线程序猿8年前 (2016-03-23)