元字符: /b: 匹配一个位置,可以是一个串中间的某个位置,单词的开始或着结尾"er/b",匹配her,不匹配hert; "/bea" 匹配eat, 不匹配heat, . : 匹配除去换行符以外的任意字符。 * : 匹配任意数量,指*前边的内容你个可以连续重复使用任意次(可以是0次)以使整个表达式得到匹配。 例子: /bhi/b.*/blucy/b; : 意思是先是一个单词hi,然后是任意数量的任意非换行字符,最后事lucy单词相当于{0,} /d: 匹配一位数字(0-9); 例子: 0/d/d-/d/d/d/d/d/d/d/d : 匹配以0开头,然后是两个数字,然后是一个连字号"-",最后是8个数字。 : 0/d{2}-/d{8}; {}内地数字表示/d 连续出现2/8 次 /s: 匹配任意的空白字符,包括空格,制表符,换行符,中文全角空格等, /w: 匹配字母,数字,下划线,或者汉字 例子: /ba/w*/b: 匹配以字母a开头的单词,先是字母a后是任意数量的字母或数字下划线汉字等 +:使匹配重复至少一次,相当于{1,} 例子:/d+: 匹配一个或多个连续的字符 {}:具体指定匹配多少次 例子: {2}: 匹配两次; {5, 12}: 至少匹配5次,最多匹配12次 {4,}: 至少匹配4次, ^ : ^不在[]中括号内时,匹配字符串开始,整个字符串的开始位置,不可能是中间的某个位置 $ :匹配字符串结束,整个字符串的结束位置,不可能是中间的位置 ? :匹配0次或者1次。相当于{0,1} []:匹配中括号内的任意字符 例子: [aeiou]: 匹配以一个英文元音字母, [.?!]: 匹配.或?或! /(?0/d{2}[)-]?/d{8}: "("")"也是元字符。/)? 匹配0个活1个(; 0:匹配0; /d{2}: 匹配两个数字 [)-]? : 匹配0/1个)/-; /d{8} 匹配8个数字;(010)88886666,或022-22334455,或02912345678 分支条件: | 例子:0/d{2}-/d{8}|0/d{3}-/d{7}: 匹配两种以-分割的电话号码,010-12345678 或者 0376-1234567 注意分支条件的顺序: 例子: /d{5}-/d{4}|/d{5}: 匹配美国的邮政编码,使用-间隔的9位数字,或者5位数字。 如果改为 : /d{5}|/d{5}-/d{4},则会只匹配5位邮政编码,或者9位号吗的前5位,因只有/d{5}起作用。 分组:() 指定一段表达式为一组,这个组可以指定是否重复及重复次数 (/d{1,3}/.){3}/d{1,3}: 一个简单的ip地址格式匹配 ((2[0-4]/d|25[0-5]|[01]?/d/d?)/.){3}(2[0-4]/d|25[0-5]|[01]?/d/d?) 反义: /S : 与/s相反 /W : 与/w相反 /D : 与/d相反 /B : 与/b相反 [^x]: 匹配除去x以外的任意字符 [^aeiou]: 匹配除去aeiou这几个字符的任意字符 向后引用: 从左向右,以分组的做括号为标志,第一个出现的分组编号为1,第二个为2,以此类推。 例子: /b(/w+)/b/s+/1/b : 匹配像 go go. ha ha ;等重复的字符串 分类 代码/语法 说明 捕获 (exp) 匹配exp,并捕获文本到自动命名的组里 :/b(/w+)/b/s+/1/b (?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成 (?'name'exp) : /b(?<Word>/w+)/b/s+/k<Word>/b (?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号 零宽断言 (?=exp) 匹配exp前面的位置 (?<=exp) 匹配exp后面的位置 (?!exp) 匹配后面跟的不是exp的位置 (?<!exp) 匹配前面不是exp的位置 注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 注: 零宽断言只匹配位置, 接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像/b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。最好还是拿例子来说明吧: 断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。 (?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如/b/w+(?=ing/b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。 (?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=/bre)/w+/b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。 假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=/d)/d{3})+/b,用它对1234567890进行查找时结果是234567890。 下面这个例子同时使用了这两种断言:(?<=/s)/d+(?=/s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)。 前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u, 我们可以尝试这样: /b/w*q[^u]/w*/b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的/w*/b将会匹配下一个单词,于是/b/w*q[^u]/w*/b就能匹配整个Iraq fighting。负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:/b/w*q(?!u)/w*/b。 零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:/d{3}(?!/d)匹配三位数字,而且这三位数字的后面不能是数字;/b((?!abc)/w)+/b匹配不包含连续字符串abc的单词。 同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])/d{7}匹配前面不是小写字母的七位数字。 请详细分析表达式(?<=<(/w+)>).*(?=<///1>),这个表达式最能表现零宽断言的真正用途。 一个更复杂的例子:(?<=<(/w+)>).*(?=<///1>)匹配不包含属性的简单HTML标签内里的内容。(<?(/w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<///1>)。注意后缀里的//,它用到了前面提过的字符转义;/1则是一个反向引用,引用的正是捕获的第一组,前面的(/w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b>和</b> 之间的内容(再次提醒,不包括前缀和后缀本身)。 192.168.0.2 /a 报警字符(打印它的效果是电脑嘀一声) /b 通常是单词分界位置,但如果在字符类里使用代表退格 /t 制表符,Tab /r 回车 /v 竖向制表符 /f 换页符 /n 换行符 /e Escape /0nn ASCII代码中八进制代码为nn的字符 /xnn ASCII代码中十六进制代码为nn的字符 /unnnn Unicode代码中十六进制代码为nnnn的字符 /cN ASCII控制字符。比如/cC代表Ctrl+C /A 字符串开头(类似^,但不受处理多行选项的影响) /Z 字符串结尾或行尾(不受处理多行选项的影响) /z 字符串结尾(类似$,但不受处理多行选项的影响) /G 当前搜索的开头 /p{name} Unicode中命名为name的字符类,例如/p{IsGreek} (?>exp) 贪婪子表达式 (?<x>-<y>exp) 平衡组 (?im-nsx:exp) 在子表达式exp中改变处理选项 (?im-nsx) 为表达式后面的部分改变处理选项 (?(exp)yes|no) 把exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no (?(exp)yes) 同上,只是使用空表达式作为no (?(name)yes|no) 如果命名为name的组捕获到了内容,使用yes作为表达式;否则使用 no (?(name)yes) 同上,只是使用空表达式作为no