正则表达式
正则表达式到底是什么东西?
百度百科定义:
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
简单来说,正则表达式就是一种 格式,用来匹配符合这种格式的字符串
入门
学习正则表达式的最好方法是从例子开始,理解例子之后再自己对例子进行修改,实验
先看简单例子:
假设在一篇英文里查找hi,你可以使用正则表达式hi。
这几乎是最简单的正则表达式,可以精确比配:由两个字符组成,前一个是h,后一个是i。通常,搜索工具会提供忽略大小写的选项,如果选中可以匹配hi
,HI
,Hi
,hI
这四种情况中的任意一种。
不幸的是,很多单词里包含hi这两个连续的字符,比如him,history,high等等。用hi来查找的话,这里边的hi也会被找出来。如果要精确地查找hi这个单词的话,我们应该使用\bhi\b。
再看稍复杂的例子
任务
: 匹配电话号码 (010)88886666,或022-22334455,或02912345678
不用正则表达式,Java代码好实现吗?
进阶
元字符
正则表达式 由一些普通字符
和一些元字符
(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符则具有特殊的含义,下面介绍常用的元字符。
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
| | 将两个匹配条件进行逻辑"或"运算 |
字符转义
如果想查找元字符本身,比如查找 .或\b,就出现了问题,因为这两个在正则表达式里被解释成其他含义
,这时可以用\
来取消这些字符的特殊意义。
例如:
aaa.com 可匹配 aaa.com
aaa\\b 可匹配 aaa\b
重复
要点: 匹配前面的子表达式
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
例子:
www\d+ 匹配www后面跟一个或更多数字
\d{2,8} 匹配2到8位数字
字符集合
字符集合[xyz]。匹配所包含的任意一个字符
。例如,“[abc]”可以匹配“plain”中的“a”。
要想查找数字
,字母
,空白
是很简单的,因为已经有了对应这些字符集合的元字符
,但是如果想匹配没有预定义元字符的字符集合(比如a,e,i,o,u),应该怎么办?
很简单,[aeiou] 就代表匹配其中任一字符
我们也可以轻松地指定一个字符范围
:
[0-9] 代表的含意与 \d 完全一致的:一位数字
[a-z0-9A-Z_] 也完全等同于 \w (如果只考虑英文的话)
下面是一个更复杂的表达式:(?0\d{2}[) -]?\d{8}
分析:
首先是一个转义字符 (,他能出现0次或1次,然后是一个0,后面跟着2个数字 \d{2}
然后是一个字符集合 [) -]?,表示 )或- 出现0次或1次
最后是8个数字 \d{8}
分支条件
正则表达式中的分支条件,就指的是有几种规则:用“|”把不同的规则分开
来看下例子:
① 0\d{2}-\d{8}|0\d{3}-\d{7}: 匹配两种以连字号分隔的电话号码;一种是三位区号8位本地号(例如:010-12345678),另外一种规则则是4位区号7位本地号(例如:0315-8834524)
② \d{5}-\d{4}|\d{5}: 需要注意的是使用分支条件是一定要注意分支条件的顺序,如果改成\d{5}|\d{5}-\d{4}这个样子的话,那么只会匹配五位数字而不会匹配后面的四位数字(例如:我们利用第二个匹配12345-1234,它只会匹配12345,原因是:正则表达式是从左到右依次匹配,如果满足了某个分支的话它就不会再管其他分支了)
分组
前面已经提到怎么重复单个字符
但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式
(也叫做分组),然后你就可以指定这个子表达式的重复次数了。
下面以IP地址的正则表达式为例:
简易版:(\d{1,3}.){3}\d{1,3}
要理解这个表达式,请按下列顺序分析它:
\d{1,3} 匹配1到3位的数字,
(\d{1,3}.){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?)。
反义
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
例子:
\S+匹配不包含空白符的字符串。
<a[^>]+> 匹配用尖括号括起来的以a开头的字符串。
后向引用
待补充
零宽断言
接下来的四个用于匹配
在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\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。
负向零宽断言
其实就是 零宽断言的反义
零宽度负预测先行断言
(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
同理,我们可以用(?<!exp), 零宽度负回顾后发断言
来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。
贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常是匹配尽可能多的字符
以 a.*b
为例,它将匹配最长的以a开始,以b结束的字符串。 用它来匹配字符串:aabab , 它会匹配到整个字符串。 这被称为贪婪模式
有时我们需要 懒惰
匹配,也就是匹配尽可能少的字符
懒惰限定符:
代码/语法 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
上路
-
校验密码强度
必须是包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间。
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
-
检验中文
^[\u4e00-\u9fa5]{0,}$
-
校验身份证号
15位
^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$
18位:
^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$
-
由数字、26个英文字母或下划线组成的字符串
^\w+$
项目中使用:
- 字符串替换
var __scripts = document.scripts;
var __jsHostname = __scripts[__scripts.length - 1].src.replace(/^(http:|https:)?\/\//, '').replace(/\/.*/, '');
- 排查
.*<%@ *include *file(.*?)(\\.js|\\.css)(.*)
.*< *script *type(.*)src(.*)
.*< *link href([^:]*)
.*@import(.*)
.*(createElement\\((\"|')script(\"|')\\))(.*)
.*< *img* src *
JavaScript中的正则
RegExp对象
RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。
创建RegExp对象
var patt=new RegExp(pattern,modifiers);
或更简单的方法
var patt=/pattern/modifiers;
模式描述了一个表达式模型。
修饰符(modifiers)描述了检索是否是全局,区分大小写等。
RegExp 修饰符
修饰符用于执行不区分大小写和全文的搜索
i- 修饰符是用来执行不区分大小写的匹配
g- 修饰符是用于执行全文的搜索
RegExp对象方法
方法 | 描述 |
---|---|
compile | 在 1.5 版本中已废弃。 编译正则表达式。 |
exec | 检索字符串中指定的值。返回找到的值,并确定其位置。 |
test | 检索字符串中指定的值。返回 true 或 false。 |
toString | 返回正则表达式的字符串。 |
支持正则表达式的 String 对象的方法
方法 | 描述 | 返回结果 | FF | IE |
---|---|---|---|---|
search | 检索与正则表达式相匹配的值。 | 匹配结果的起始位置 | 1 | 4 |
match | 找到一个或多个正则表达式的匹配。 | 以‘,’分割的满足条件的结果 | 1 | 4 |
replace | 替换与正则表达式匹配的子串。 | 返回替换后的新 | 1 | 4 |
split | 把字符串分割为字符串数组。 | 一个字符数组 | 1 | 4 |
RegExp 对象属性
属性 | 描述 |
---|---|
constructor | 返回一个函数,该函数是一个创建 RegExp 对象的原型。 |
global | 判断是否设置了 "g" 修饰符 |
ignoreCase | 判断是否设置了 "i" 修饰符 |
lastIndex | 用于规定下次匹配的起始位置 |
multiline | 判断是否设置了 "m" 修饰符 |
source | 返回正则表达式的匹配模式 |