正则(RegExp)的基础语法差不多,但是在不同的编程语言中是有差异的。
不管那么多,先理清楚正则的基础:完成搜索和替换。
1.量词元字符:
贪婪匹配和懒惰匹配:量词 * , + { } 默认贪婪,会尽可能多的匹配。而懒惰匹配就是尽可能少的匹配。
什么是尽可能多,尽可能少?
例子:living in <b>AK</b> and <b>HI</b>
贪婪匹配:<[bB]> .*<\/[bB]> 结果: living in <b>AK</b> and <b>HI</b>
懒惰匹配:<[bB]> .*?<\/[bB]> 结果:living in <b>AK</b> and <b>HI</b>
贪婪量词和懒惰量词:
2.位置元字符:
1> 单词边界 :
\b (\b匹配的是字符之间(一边是\w匹配的字母数字下划线,另一边是\W匹配的字符)的一个位置)
如果想匹配以字符序列开头的单词,就在前面加上\b;
如果想匹配以字符序列结尾的任意单词,就在后面加上\b;
如果想匹配子符序列本身,就要在单词前后都加上\b。
单词cat , \bcat 能够匹配到 catijnn 等 ,cat\b能够匹配到 jushcat 等 ,\bcat\b只能匹配cat。
2>非单词边界:
\B,\b的反义,匹配的非单词边界。比如用来匹配符号边界。
比如,\B- \B ,匹配一个前后都不是单词边界的连字符,e-li不能匹配,只有这样的 color - coded才能匹配上。
3> \>和\<,它们和\b的区别就是:\b可以用在开头和结尾,而它们只能用在开头或结尾。
3.好用的反向引用:
为什么需要反向引用?
<h1>hello </h1> 匹配所有的h标签很简单,<[hH][1-6]> . *?<\/[hH][1-6] (这里懒惰匹配了),不过它会把下面的情况也匹配上。
<h2>world </h3> 明显,错了。
这个时候,我们需要反向引用。
反向引用,指的是先前的子表达式。把反向引用想象成一个变量,我们子表达式匹配的内容就存放到变量中,下一次我们调用就好了。
<[hH] ( [1-6 ] ) > .*? <\/[hH] \1 > 这样写就对了。
\1是什么?——就是子表达式匹配到的变量,\1在这里就是2。当<h2>world </h3>时,就匹配不成功。
第几个子表达式,就写 \ 几。
4.环视:
为什么需要环视?
ACC01 : $23.124.333 把价钱匹配出来。 \$[0-9.]+ 结果 $23.124.333
要求不要把$符号也匹配出来, 无法满足这个需求。([0-9.]+ 结果 01 : $23.124.333 )
1>环视向后查看:?<= ,(?<=\$)匹配$字符,但最终的结果没有它。 于是(?<=\$)[0-9.]+ 的结果:23.124.333
环视向前查看:?= ,(?= : )匹配:字符,但最终的结果没有它。于是(?=:) \w+ 的结果是 ACC01
(向前查看很多语言都支持,向后查看很多都不支持)
2>否定式环视:会查看不匹配指定模式的文本。
否定向前查看 : (?!) 否定向后查看: (?<!)
I paid $30 for 100 apples 肯定向前(?<=\$)\d+ 匹配价格 30
否定向前 \b(?<!\$)\d+ \b 匹配数量100 , 仅当数字前面的字符不是$时才匹配。为什么要\b , 因为不加会把$30的0也匹配上。
5.嵌入式条件(不是很被支持)
1>搭配反向引用:(?(反向引用)true | false) : ?表示这是一个条件,仅当反向引用这个条件符合时,用true方法匹配,否则用false。
给一堆电话号码:要么出现括号,就必须成对且不要-,要么就别出现括号全用-符。只有前两个符合要求。
123-456-7890 就可用条件搭配反向引用来判断( 有没有出现,如果出现,就必须出现) 且不立即出现 - ,如果不出现就一直是-
(123) 456-7890
(123) -456-7890
(123 -456 -7890
1234567890
123 456 7890 (\()?\d{3}(?(1)\)|-)\d{3}-\d{4} ( \( ) ? 这是一个子表达式,检查有没有出现( , (?(1)\)|-) 这是一个条件,如果出现了\1(即‘(’符号) ,就要匹配 ) 符号,如果没出现就匹配 - 符号 。这样,括号终于可以判断括号成对了。
2>搭配环视条件:区别就是把反向引用换成环视表达式。
6.大小写替换
<h1>Welcome to my home </h1>
替换成大写 正则表达式 :(<[hH]1>)(.*?) (<\/[hH]1>) 替换:$1\U$2\E$3
结果:<h1>WELCOME TO MY HOME</h1>
三个子表达式,$1包含开始标签 <[hH]1> , \U$2\E把之间的$2转换成大写,$3是个结束标签 。
JS的正则
1.exec : RegExp.exec(String) 该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。
2.match : String.match(RegExp) 存放匹配结果的数组。该数组的内容依赖于 regexp 是否具有全局标志 g。 如果没找到匹配结果返回 null 。
3.replace : String.replace(RegExp , String2) 把String中的RegExp替换成String2。
4.search : 检索与正则表达式相匹配的子字符串,并返回子串的起始位置。没匹配到,返回-1。String.search(RegExp)
5.split : 按约定字符串或字符串规则拆分成数组。
6.test : 判断是否匹配,返回true或false 。String.test(RegExp)
7.js有 g : 全局搜索 i:不区分大小写 合并为gi
8.js的反向引用 : $` (反引号) 返回所匹配字符串之前内容。 $' (单引号) ,返回所匹配字符串之后所有内容。 $+返回最后一个匹配的子表达式。 $&返回所匹配到的所有内容。
9.js不支持\A和\Z。