正则表达式
来源:互联网 发布:sql select count 1 编辑:程序博客网 时间:2024/06/12 01:23
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码,最多的用途就是匹配带有一定规律的字符串
常用元字符(metachracter)
.
- 匹配除换行(\r\n
)以外的任意字符\w
- 匹配包括下划线的任何单词字符(unicode),类似但不等价于[A-Za-z0-9_]
\s
- 匹配任意的不可见字符,等价于[\f\n\r\t\v]
\d
- 匹配数字\b
- 匹配单词的开始或结束^
- 匹配字符串的开始$
- 匹配字符串的结束
\b
与^
和$
看起来\b
与^
和$
相同,但是是有差异的
\b
是表示一个单词的边界,一个单词例如一连串的英文和数字、或者一句中文^
和$
是表示一个字符串的开始和结尾,分割字符串的仅是那些不可见字符
/b44/b | 匹配字符串 | !@#$%44&*() | -> 匹配成功,因为"44"这个字符串的左右都不是英文数字,所以这里"44"就是一个单词^44$ | 匹配字符串 | !@#$%44&*() | -> 匹配失败,因为这个字符串的开头不是'4'而是'!',结尾不是'4'而是')'/b44/b | 匹配字符串 | 44出32 | 和 | 4432出 | -> 前者成功,后者失败,前者是因为'出'和'4'并不是同种类型的字符,所以这里有三个单词"44"和"出"和"32";而后者"4432"是一个单词,并不满足"44"之后是单词结尾^44 | 匹配字符串 | 44出32 | 和 | 出4432 | -> 前者成功,后者失败,这里只用考虑整个字符串是不是以"44"开头的
另外有些正则表达式处理提供 多行(Multiline) 选项,使得
^
和$
也匹配\n
和\r
的前后位置
JavaScript RegExp \b 元字符
正则匹配中 ^ $ 和 \b 的区别
JavaScript multiline 属性
字符转义
和很多语言一样,也是用\
符号来转义,因此在JavaScript当中有时候可能要两次转义
重复限定符
元字符只是匹配一个位置或者字符,当我们想匹配多个或者不确定个数元字符时,就要搭配上下面这些限定符使用了
*
- 重复次数 >= 0+
- 重复次数 >= 1?
- 重复次数 == 0 或 重复次数 == 1{n}
- 重复次数 == n{n,}
- 重复次数 >= n{n,m}
- m >= 重复次数 >= n
0\d{2}-\d{8} - 匹配上010-12345678\ba\w*\b - 匹配一个单词以'a'开头,之后任意个数字字母,直到单词的结尾Windows\d+ - 匹配'Windows'后面跟上不少于一个数字
字符类
如果没有特定的元字符,比如只匹配’c’、’m’、’d’,此时用[]
框住,就像一个集合一样
[cmd] - 只匹配'c'或'm'或'd'这三个字符[.!?] - 只匹配'.'或'!'或'?'这三个标点符号(这里的'.'必然不是元字符)
也可以在框中指定一个范围
[0-9] - 匹配数字 \(?0\d{2}[) -]?\d{8} 首先"\(?"说明一开始可以出现0次或1次'(' 然后是必须要出现一个'0' 接着是两个数字 之后是出现0次或1次'('或' '或'-' 最后是8个数字可以匹配:020-12345678、(020)12345678、02012345678
分枝条件
不难看出之前那个表达式\(?0\d{2}[) -]?\d{8}
同样可以匹配例如(020-12345678
或010)12345678
这种不正确的格式,正则表达式中用|
来表示分枝,只要满足一个分支都算匹配成功,且当从左至右第一个分支匹配成功后,后面的分支都不会参与测试
\(0\d{2,3}\)[- ]?\d{8}|0\d{2,3}[- ]?\d{8} - 解决上面错误格式问题,以及将区号扩展为3或4位
分组
使用()
来指定子表达式的方式叫做分组,这样我们就可以加上限定符重复多个字符了
(\d{1,3}\.){3}\d{1,3} - 一个用来简单匹配IP地址的表达式,这里重复\d{1,3}\.这个组3次,最后加上\d{1,3},但是我们知道IP地址每位最大是255,因此需要分枝 ((2[0-4]\d|25[0-5]|[01]?\d?\d)\.){3}(2[0-4]\d|25[0-5]|[01]?\d?\d) - 这样就可以解决最大数字问题了
反义
查找不属于某个元字符(或者字符类、分组)的字符,有以下反义
\W
- 匹配不包括下划线的任何非单词字符(unicode)\S
- 匹配任意不是空白字符的字符\D
- 匹配任意不是数字的字符\B
- 匹配不是单词开头或结束的位置[^xyz]
- 匹配除’x’或’y’或’z’以外的任意字符
\S+ - 匹配不包含空白字符的字符串 <a[^>]+> - 匹配用'<>'框住且以'a'开头的字符串
后向引用
分组后,从左至右以(
作为分组标志,默认从1开始作为组号递增,后向引用用于重复搜索前面某个分组匹配的文本
\b(\w+)\b\s+\1\b - 可以匹配类似"go go"(其中"\1"为"go")、"cmd cmd"(其中"\1"为"cmd"),但不能匹配"cmd cmdd"、"123 234"
当然可以自己指定子表达式(某个分组)的组名,使用(?<Word>\w+)
或(?'Word'\w+)
,这样相当于将子表达式\w+
命名为Word
了,反向引用语法为\k<word>
,这样上面那个例子可以写为
\b(?<cmd>\w+)\b\s+\k<cmd>\b
其实组号分配并没那么简单,组号0代表整个正则表达式,组号分配时会扫描表达式两遍,第一遍只给未命名组分配,第二遍只给命名组分配
零宽断言
类似于\b
、^
、$
用于匹配一个位置,并且应该满足一定条件(断言)
零宽度正预测先行断言
(?=exp)
- 匹配满足表达式之前的位置
\b\w+(?=ing\b) - 匹配一个以"ing"结尾的单词的前面部分
零宽度正回顾后发断言
(?<=exp)
- 匹配满足表达式之后的位置
(?<=\bre)\w+\b - 匹配一个以"re"开头的单词的后面部分(?<=\s)\d+(?=\s) - 匹配两端都是空格字符的一串数字
零宽度负预测先行断言
表达式\b\w*q[^u]\w*\b
本来只是想确定这个单词中含有’q’且后面不是’u’,但是[^u]
必须匹配上一个字符,因此这一串不能匹配上”aiq”这种以’q’结尾的单词,却能匹配上”aiq be”这种两个单词以空格分开且前一个单词结尾是’q’的字符串,如果只用之前所说的方法,又要写上一长串的分枝了 (?!exp)
- 匹配不满足表达式之前的位置
\d{3}(?!\d) - 匹配一串数字的最后三个数字\b((?!abc)\w)+\b - 匹配一个不包含"abc"子字串的单词\b([^q\s]*q(?!u)[^q\s]*)+\b - 就解决上面那个问题了
零宽度负回顾后发断言
(?<!exp)
- 匹配不满足表达之后的位置
(?<![a-z])\d{7} - 匹配7个连续的数字,且第一个数字前不是小写字母(?<=<(\w+)>).*(?=<\/\1>) - 匹配不包含属性的简单HTML标签内里的内容(例如<b>123</b>中的123)
注释
(?#comment) - 最好启用忽略模式里的空白符,这样表达式中可以添加任意的空格、换行字符,且#
后面直到换行之前的都将被当作注释,例如之前(?<=<(\w+)>).*(?=<\/\1>)
可以写为
(?<= # 断言要匹配的文本的前缀<(\w+)> # 查找尖括号括起来的字母或数字(即HTML/XML标签)) # 前缀结束.* # 匹配任意文本(?= # 断言要匹配的文本的后缀<\/\1> # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签) # 后缀结束
分组语法整理
下面整理以上常用的分组语法(其中exp
代表表达式)
(exp)
- 匹配exp,并捕获匹配得到的文本到自动命名的组内(?<name>exp)
- 匹配exp,并捕获匹配得到的文本到自主命名为name
的组内(?:exp)
- 匹配exp,但不捕获文本,也不分配组号(?=exp)
- 匹配满足表达式之前的位置(?<=exp)
- 匹配满足表达式之后的位置(?!exp)
- 匹配不满足表达式之前的位置(?<!exp)
- 匹配不满足表达式之后的位置
限定符的贪婪与懒惰
- 贪婪 - (默认)匹配尽可能多的字符
- 懒惰 - 匹配尽可能少的字符,在限定符后添加
?
(*?
、+?
、??
、{n,m}?
、{n,}?
)
现有字符串aababa.*b - 匹配得到aababa.*?b - 匹配得到aab和ab
处理选项
IgnoreCase
- 忽略大小写Multiline
- 多行模式,使得^
和$
也匹配\n
和\r
的前后位置Singleline
- 单行模式,使得.
与所有字符匹配,包括\n
IgnorePatternWhitespace
- 忽略非转义空白,并启用#
注释ExplicitCapture
- 显式捕获,仅捕获已被显式命名的分组
平衡组/递归匹配
考虑到有嵌套关系的层次结构,例如xx <aa <bbb> <bbb> aa> yy
这个字符串怎样匹配到最外层的<>
所含内容
以下是.Net Framwork支持的语法结构
(?'group')
- 把捕获的内容命名为group并压入堆栈(Stack)(?-group)
- 从堆栈顶弹出名为group的捕获内容,若堆栈为空,则此次分组匹配失败(?(group)yes|no)
- 如果堆栈上存在以group为名的捕获内容,则匹配yes部分的表达式,否则匹配no部分的表达式(?!)
- 由于没有后缀表达式,试图匹配总是失败
<[^<>]*(((?'Open'<)[^<>]*)+((?'-Open'>)[^<>]*)+)*(?(Open)(?!))>< #最外层的左括号 [^<>]* #最外层的左括号后面的不是括号的内容 ( ( (?'Open'<) #碰到了左括号,在黑板上写一个"Open" [^<>]* #匹配左括号后面的不是括号的内容 )+ ( (?'-Open'>) #碰到了右括号,擦掉一个"Open" [^<>]* #匹配右括号后面不是括号的内容 )+ )* (?(Open)(?!)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败> #最外层的右括号
js中运用正则表达式
RegExp
对象
js中正则表达式对象,通过下面两种方式可以创建
var re = new RexExp(str, attr) // str是正则表达式字符串,attr是可选参数var re = /str/attr // str是正则表达式,用两个/包围,后面attr是可选参数
可选参数(修饰符)
i
- 忽略大小写敏感g
- 执行全局匹配m
- 执行多行匹配
常用的是
g
,比如用/\d+/
和/\d+/g
去匹配字符串1a2b3d4c
,前者只能匹配到一个结果['1']
,后者可以匹配到四个结果['1', '2', '3', '4']
可以使用正则的函数
以下样例中用 re
表示正则表达式,用s
表示字符串
s.match(re)
匹配字符串,返回匹配结果
s.search(re)
返回匹配上的第一个字串的偏移量
s.replace(re, text)
将匹配结果替换为其他文本
s.split(re)
将匹配的子串作为分隔符,返回分割后的数组(此函数无视g
修饰符,默认全文替换)
re.exec(s)
对字符串查找,返回找到的子字符串和偏移量(此函数无视g
修饰符,只返回第一个结果)
re.test(s)
检测字符串,仅当完全匹配上时返回true
资料整理
正则表达式30分钟入门教程
在线正则表达式测试
正则表达式_百度百科
js正则函数match、exec、test、search、replace、split使用介绍集合
JavaScript RegExp 对象
- 【正则表达式】正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- 正则表达式
- java使用BufferedImage操作合成图片
- Cordova通过CordovaPlugin插件调用 Activity
- hadoop 里常用命令
- uboot启动参数设置分类及方法
- 写一个python脚本,实现简单的http服务器功能:
- 正则表达式
- 最好的关系,是我懂你的不容易
- 管道和FIFO
- javascript事件
- #if DEBUG
- 我是如何打败拖延症的
- 百度天气预报接口
- 结构型--适配器模式
- Android 获取并显示远程图片 Picasso框架的使用