正则表达式学习笔记
元字符
\b 代表单词的开头或结尾,也就是单词分隔,例如想找出 How are you?这句的想找出单词are 就可以使用 \bare\b
. 代表匹配除了换行以外的任意字符
\d 表示一位数字 比如 \d-\d 就可以匹配 2-2 3-3 这样
\w 字母或数字或下划线或汉字
\s 匹配任意空白字符
^ 字符串的开头
$ 字符串的结尾
重复
* (重复0次或更多次)代表前边的内容可以连续重复使用任意次以使整个表达式得到匹配。
+ 一次或更多次
? 一次或0次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
示例:
例1:下列字符串 How are you? Fine Thankyou. And you? 如果想找出How和Fine之间的所有字符串可以用 How\b.*\bFine\b
例2:要想匹配 0931-3334224 这样的字符串 只需 \d{4}-\d{7}
字符类
比如想找预定义的字符集合那就要用到这一节的内容了。
例如
[aeiou] 如果你要匹配任意一个元音字母可以使用
[.?!] 匹配这三个标点符号
[0-9] 匹配0-9的任意一个数字 与\d完全一致
[a-z0-9A-Z] 也完全等同于\w(如果只考虑英文的话)
\(?0\d{2}[) -]?\d{8} 这个表达式可以匹配几种电话号码像(010)8888666或020-2236355。\(? 表示可以有一个或没有左括号 0\d{2} 表示第一个数字为0后两个字符是两个数量类似 010 020 这些。[)-]? 表示有或者没有右括号) 或 - 号。\d{8}表示8位数字
分支条件
不幸的是,刚才\(?0\d{2}[) -]?\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{4} \d重复4次,但是如果要重复多个字符我们该怎么办答案是可以用小括号来指定分组,也就是可以指定这个子表达式的重复次数了,你也可以对子表达式进行一些其它的操作
(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})
反义
有时需要表示 不等于 这种条件。。比如 不等于 数字 不等于字母等。这里就要用到反义。
反义就是把原先不反义的变成大写就成反义了如果 \D 非数字
后向引用
后向引用简单的说就是后面的引用前面的。引用前面的什么呢,引用前面里的括号里的。括号里的我们前面分组。那么意思就是后面的可以引用前面分组的内容。怎么引用呢? \1 就代表第一个分组。\2就代表第二个分组。以此类推。
\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。
你也可以指定自己的组名语法:(?<Word>\w+),这样就把\w+的组名指定为Word了。
要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。
零宽断言
留着以后学习
负向零宽断言
留前瞻以后学习
贪婪与懒惰
当正则表达式中包含能接受重复限定符时,通常行为是(在使整个表达式匹配的前提下)匹配尽可能多的字符。例如:a.*b,它将会匹配最长以a开始,以b结束的字符串。如果用它来搜索aabab的话。它会区配整个字符 。这种称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
平衡组/递归匹配
比较复杂,以后再看。