正则表达式(Regular Expression)
首次接触到正则表达式的时候,简直看不懂这是什么鬼,无从下手。学习后发现,其实正则表达式也就类似于数学运算。数学运算中,我们只要记住数学运算中的+、-、*、/、()等这些数学运算符的规则,再做一些练习,以后读懂和使用就不成问题了,正则表达式也是如此。所以下面讲一下正则表达式中的字符和对应的规则,只要跟着下面一步一步来,再做一下练习,你会发现正则表达式并没有那么难,so easy,以后再也不怕啦。
1、 简介
正则表达式是一种文本模式,包括普通字符和特殊字符(称为元字符)。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
也许你已经使用过正则表达式了,比如在使用*或?通配符来查找硬盘上的文件。比如*.txt就会查找所有以.txt结尾的文件。
应用:正则表达式在很多应用软件中都可使用。如Linux、PHP、C#、JAVA等等
2、 语法
正则表达式是由普通字符和特殊字符(即“元字符”)组成的文字模式。
普通字符:大写字母、小写字母、数字、标点符号和一些其他符号。(除元字符外的所有可打印和不可打印字符)。
1) 大小写字母、数字、标点符号(除特殊字符)
2) 非打印字符:
字符 | 描述 |
\cx | 匹配由x指明的控制字符,如\cM匹配一个control-M或回车符。X必须是字母,否则c视为一个原义的‘c’字符。 |
\f | 换页符 |
\n | 换行符 |
\r | 回车符 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等。等价于[\f\n\r\t\v] |
\S | 匹配任何非空白字符,等价于[^\f\n\r\t\v] |
\t | 制表符 |
\v | 垂直制表符 |
特殊字符:(即“元字符”)就是正则表达式中定义了有特殊含义的字符。
1) 限定符:指定出现次数,限定符有以下6种。
限定符 | 描述 | 例子 |
* | 匹配前面的子表达式0次或多次 | zo*能匹配z、zoo等。等价于{0,} |
+ | 匹配1次或多次 | zo+能匹配zo、zoo,不能匹配z。等价于{1,} |
? | 匹配0次或1次 | zo?能匹配z和zo。等价于{0,1} |
{n} n为非负整数 | 匹配n次 | zo{2}能匹配zoo、zooms等。 |
{n,} n为非负整数 | 最少匹配n次 | zo{2,}能匹配zoo、zooo、zoooo等。 |
{n,m} nm为非负整数 | 最少匹配n次,最多m次 | zo{2,3}能匹配zoo、zooo。注意逗号之间不要有空格。 |
练习:
正则表达式 | 描述 |
/Chapter [1-9][0-9]*/ | [1-9]表示1-9中的任一数字可以出现一次 [0-9]*表示0-9中的任意数字可以出现0次或多次 |
/Chapter [1-9][0-9]?/或 /Chapter [1-9][0-9]{0,1}/ | 表示只匹配两位数字的章节。 |
贪婪与非贪婪:*、+、?限定符是贪婪的,在它们后面加上?就是非贪婪的。
贪婪:在所有内容中匹配,直到所有内容中没有匹配成功的内容为止。
非贪婪:在内容中从头开始匹配,在遇到第一个匹配不成功的即停止。而贪婪是匹配到所有内容。
如:字符串内容是<h1>12345<h1>,贪婪/<.*>/,会匹配到<h1>12345<h1>;非贪婪/<.*?>/会匹配到<h1>。
2) 定位符:顾名思义,定位符即可以标识正则表达式的位置,如行首、行尾、边界。
定位符 | 描述 | 例子 |
^ | 1. 标识是字符串开始的位置。 2. 在中括号里[^],表示排除指定字符外。 | /^Chapter/指一定是Chapter开头的 [^abc]即不包含有字符abc的 |
$ | 标识是字符串结束的位置 | /[0-9]+$/指一定是数字结尾的 |
\b | 标识字边界,即字与空格间的位置 | /\bCha/指Cha是一个字的开头 /ter\b/指ter是一个字的结尾 |
\B | 非字边界匹配,即在字的中间位置,非首尾。 | /\Bapt/能匹配Chapter,不能匹配aptude,因为在aptude中是字首。 |
3) 选择:用()括起来,相邻的选择项之间用|分隔。即“或”的关系。
在正则表达式中,()会把括号内相关的匹配缓存起来(缓存以便反向引用)。
此时可以使用非捕获元(有三种?:、?=、?!)来取消缓存。如:/(hello|hi)/能匹配helloworld、hiworld等,但会缓存hello和hi;而/(?:hello|hi)/能实现同样的匹配规则,而且不会缓存。
4) 反向引用:就是可以在缓存中进行选择匹配。在查找文本中两个相同的相邻单词时就需要用到反向引用。
()内的匹配会被按顺序存储到临时缓冲区,且赋予编号1-99(最大99)。通过\num访问缓冲区(其中num表示1-99的数字)。例:
Is is the cost of of gasoline going up up?句子中有重复单词,现在设法找出重复的单词并且只保留重复单词中的第一个。如:/b([a-z]+) \1\b/gi。其中\1表示指定第一个子匹配项。i标示忽略大小写。g是全局标记,将表达式应用到输入字符串中能够查找到的尽可能多的匹配项。
5) 非捕获元
字符 | 描述 | 例子 |
(?:pattern) | 匹配pattern但不获取结果;不存储。 | ‘industr(?:y|ies)’就是一个比’industry|industries’更简略的表达式。但技术实现本身是一样的。 |
(?=pattern) | 正向预查,在任何匹配pattern的字符串开始的位置匹配查找字符串;不存储。 | ‘windows(?=95|98)’在一次匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 |
(?!pattern) | 负向预查,在任何不匹配pattern的字符串开始的位置匹配查找字符串;不存储。 | ‘windows(?=95|98)’能匹配window3.1中的windows,而不能匹配windows95中的windows。同?=从最后一次匹配之后开始下一次匹配的搜索。 |
6) 其他元字符
字符 | 描述 | 例子 |
\ | 转义。将下一个字符标记为特殊字符或原义字符或向后引用或八进制转义符 | ‘n’匹配字符n,’\n’则匹配一个换行符 |
. | 除换行符’\n’之外的任何单个字符 | 若要包含’\n’,需使用“(.|\n)” |
x|y | 匹配字符x或y | ‘z|food’能匹配z或food |
[xyz] | 字符集合。匹配所包含的任意一个字符。 | ‘{abc}’可以匹配‘plain’中的a |
[^xyz] | 负值字符集合。匹配未包含的任意字符 | ‘{abc}’可以匹配‘plain’中的p、l、i、n。 |
[a-z] | 字符范围。指定范围内的任意字符 | [a-z]可以匹配任何不在a到z范围内的任意字符。 |
\d | 匹配一个数字字符 | 等价于[0-9] |
\D | 匹配一个非数字字符 | 等价于[^0-9] |
\w | 匹配任何非单词字符 | 等价于[^a-zA-Z0-9_] |
\xn | 匹配n,n为十六进制转义符。 | \x41匹配A |
\num | Num是正整数。对所获取的匹配的引用 | (.)\1匹配两个连续的相同字符 |
\n | 标识一个八进制转义值或一个向后引用 |
|
\nm |
|
|
\nml |
|
|
\un |
|
|
3、 运算符优先级:同数学运算符一样,运算符有固定的优先级,以下为运算符优先级顺序:
运算符 | 描述 |
\ | 转义符 |
()、(?:)、(?=)、[] | 圆括号和方括号 |
*、+、? 、{n}、{n,} 、{n,m} | 限定符 |
^、$、\任何元字符、任何字符 | 定位符和序列(即位置和顺序) |
| | 替换,“或”操作 |
4、 练习
题目 | 答案 |
匹配所有小写字母 | [a-z] |
所有字母和下划线 | [A-Za-z_] |
匹配所有的数字 | [0-9] |
匹配所有的数字、句号和减号 | [0-9\.\-] |
匹配所有的白字符 | [ \f\r\t\n] |
匹配 一个小写字母和一位数字组成的字符串 | ^[a-z][0-9]$ |
除了小写字母以外的所有字符 | [^a-z] |
除了‘\’、‘/’、‘^’以外的所有字符 | [^\\\/\^] |
字母a | ^a$ |
2-4个字母a | ^a{2,4}$ |
包含2或多于2个a的字符串 | ^a{2,}$ |
两个制表符 | \t{2} |
所有的两个字符 | .{2} |
所有包含一个以上的字母、数字或下划线的字符串 | ^[A-Za-z0-9_]+$ |
所有的正整数 | ^[1-9][0-9]*& |
0及所有的正整数 | ^[0-9]*& |
所有的浮点数 | ^\-?[0-9]+\.?[0-9]*& |
一个单词连续出现的位置 | \b([a-z]+) \1\b/gi |
将一个URL解析为协议、域、端口及相对路径 http://www.baidu.com:80/aaa.bbb.ccc | /(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ |
定位章节的位置 | /^(?:Chapter|Section) [1-9][0-9]*$/ |
a至z共26个字母再加一个-号 | /[-a-z]/ |
可匹配chapter但不能匹配aptitude | /ter\b/ |
5、 工具
工具:RegexBuddy 3
在线工具: https://c.runoob.com/front-end/854
转自:http://www.runoob.com/regexp/regexp-tutorial.html
还有个很棒的入门文档:http://www.92csz.com/regex/