正则表达式
在线正则表达式测试工具
http://tool.oschina.net/regex/
教程
正则表达式30分钟入门教程 http://deerchao.net/tutorials/regex/regex.htm
正则表达式中中括号的三种用途 [] - baidu_24545901的博客 - CSDN博客 https://blog.csdn.net/baidu_24545901/article/details/78836784
正则表达式 AABB_百度搜索
MySQL 正则
MySQL 仅支持很有限的一部分正则表达式
mysql regexp用法 - George_sz - 博客园 https://www.cnblogs.com/qiaoyihang/p/6166163.html
正则表达式基本语法
字符组
列出全部元素
[0123456789]
列出元素范围 >码值小的字符在前
[0-9]:数字 [a-f]:英文字母表前6个
- 并列多个元素范围**
[A-Za-z]:大小写英文字母 [0-9a-zA-Z]:数字及大写英文字母 [0-9a-fA-F]:十六进制字符
注意,用[A-z]表示英文字母是错误的,会包括几个其它字符。((参考 http://blog.csdn.net/paiooo/article/details/7037403))
- 整体匹配**
# 在开头加^,结尾加$ ^[0-9]$:仅能匹配单个数字(2 => True, 12 => False) # 比较: [0-9]:只要包含数字就能匹配(2 => True, 12 => True,A1 => True, 2A => True)
- 排除型字符组**
[^0-9]:匹配一个非数字 # 注意,是匹配表达式以外的其它字符,不是不匹配。 # 对应位置上要有匹配的字符,整个表达式才成立。 [^0-9][0-9]:匹配一个非数字紧跟一个数字 例:8 => False,18 => False, A8 => True
排除型字符组只能排除一个字符,不能排除组合。((余晟《正则指引》P27 L9))
# [^ab]:排除的是a或b,不是排除ab
- 字符组简记法(缩写)**
\d:等价于[0-9],匹配数字(Digit) \w:相当于[0-9a-zA-Z],匹配单词(Word)及数字 # \w 也匹配数字和下划线_ # 只需要匹配数字和英文字母时,应使用[0-9a-zA-Z] \s:表示空白字符(Space) # 可以匹配空格、制表符、回车符、换行符等各类打印时空白的字符
对应的排除型字符组为大写字母形式:
\D:匹配非数字 \W:匹配非英文字母、非数字、非下划线 \S:匹配任何打印时不为空白的字符
以上两类的组合可以匹配任何字符:
[\d\D]、[\w\W]、[\s\S]
注意,点号.并不能同样匹配任意字符,在默认情况下点号是不匹配换行符的。((余晟《正则指引》P84))
- 字符组集合运算**
# 取差集(C#写法) [a-z-[aeiou]]:非元音字母 # 第一个- 是元字符,表示范围,第二个- 是减号。
量词
量词是用于确定匹配次数的表达式。
数字形式
- 具体次数**
{n}:匹配n次
- 次数范围**
{m,n}:匹配m到n次,m可以为0。 {m,}:匹配m到无限次。
字符形式
- :等价于{0,},匹配任意次数。
+:等价于{1,},至少匹配1次。
?:等价于{0,1},最多匹配1次。
点号
点号. 是一个特殊的元字符,可以匹配除换行符\n 以外的任意字符。 如果要匹配换行符,可以使用单行匹配模式或“自制”通配字符组([\s\S]等)。
正则表达式实例
- 匹配HTML标签**
<[^>]+> # 开头的“<”对应标签开头,结尾的“>”对应标签结尾 # 中间的[^>]+表示“<”之后,不是“>”的(至少1个)任意字符,即标签<>内的全部字符。
提醒:开始标签、结束标签,与标签开头、标签结尾是不同的概念。
- 匹配双引号**
"[^"]*" # 开头、结尾的",对应成对的双引号。 # 中间的[^"]*表示双引号之间,不是双引号的(可以为空的)任意字符,即双引号所引的内容。
- 分类各类标签(Tag)**
所有Tag: <[^>]+> open tag:<[^/>][^>]*[^/]>,例如 # 第1个[^/>]表示,在标签内部,排除结束标签才有的“/”,[^>]表示“>”以外的其它字符。 # 因为排除型字符组必须匹配一个字符,如果标签内只有一个字符, # 与[^/>]匹配后,就没有其它字符可与[^>]匹配了(即匹配0次) # 所以[^>]后面需要加上* # 后面的[^/>]保证不会以“/”结尾。 close tag:]+>,例如 # 上述open tag、close tag 都是不带属性值的。 self-closing tag:<[^>]+/>,例如<img />
# [^>]表示排除“>”,并不需要写成[^>/]来同时排除“/”, # 因为这里匹配的已经是“/>”之前的内容了,不会混淆; # 而且,标签内部可以包含“/”(例如作为属性值的网址等)。
阿拉伯数字
[0-9]
电话号码
- 7-8位电话号码(不包括区号)**
[1-9][0-9]{6,7}
说明:[1-9]表示第1位是0以外的数字。[0-9]{6,7}表示任意数字,长度为6-7位。合计7-8位。
- 文本中所有的固定电话号码(不包括区号)**
(?<![0-9])[1-9][0-9]{6,7}(?<[0-9])
说明:(?<![0-9])表示之前不是数字,(?![0-9])表示之后不是数字,即仅匹配文本中符合规则的数字串。
- 最新手机号码**
忽略优先量词(懒惰量词、多次最小匹配)
也称为非贪婪表达式。((参考 http://www.runoob.com/regexp/regexp-syntax.html))
- 应用示例**
需要匹配<script>标签及其中间的内容,可以使用
<script type="text/javascript">[\s\S]*</script> # 使用[\s\S],是考虑到如果标签中间的内容存在换行符,也可以匹配
但如果文本中同时存在2个或多个<script>标签时,以上表达式会匹配所有的<script>标签, 甚至包含不同<script>标签之间的非Js代码。
这时可以在[\s\S]*后添加?,改为忽略优先量词,做多次最小匹配。
<script type="text/javascript">[\s\S]*?</script> # [\s\S]*?,在匹配过程时,遇到可匹配的字符时, # 先尝试跳过(忽略)本部分字符组(即[\s\S])的匹配, # 检查表达式中后续的部分(本例为</script>),能不能匹配, # 如果不能,再与本部分字符组匹配。 # 这样[\s\S]*? 之后的部分(</script>)就会先被匹配, # 最后可以得到整个表达式的一个最小匹配。
最小匹配可以有多个。在本例中可以准确匹配出多个<script>标签。
常见问题的解决思路
^ 分类 ^ 说明 ^ | 必须出现 | 某些元素必须出现 | | 可能出现 | 某些元素不出现、出现(长度不固定,或者限定为某几个元素中的一个)| | 不能出现 | 某些元素不能出现 |
起源
>最后,为了尊重传统教科书的习惯,附上正则表达式的“科班史”((余晟《正则指引》“引子”P5)):
>正则表达式发源于与计算机密切相关的两个领域:计算理论和形式语言。20世纪40年代,两位神经生理学家Warren McCulloch和 Walter Pitts研究出一种数学方式来描述神经网络的办法,它们把神经系统中的神经元描述成小而简单的自动控制单元。1956年,数学家Stephen Cole Kleene在他们研究的基础上,发表了一篇名为“神经网事件的表示法”的论文,在其中,他采用了一些称之为“正则集合(regular set)”的数学符号来描述神经网络模型。
>之后,UNIX的主要发明人Ken Thompson将这个符号系统引入了文本编辑器QED(意思是“在文本中搜索某种模式”),正则表达式由此也进入了计算机世界。随后Ken Thompson又将正则表达式引入了UNX下的文本编辑器ed,ed最终演化为大家熟悉的grep(grep得名自ed编辑器中的正则表达式搜索命令g/re/p,其中的re表示“正则表达式”)。
参考资料
《正则指引》,余晟,2012,电子工业出版社