为什么要使用正则表达式?
如果要判断一个字符串是否是合法的Email地址
可以通过提取@前后的字符串,再判断他们是否是单词和域名,但是这种方法复杂,而且代码难以复用。
但是使用正则的话,可以直接写正则表达式,再判断每个字符串是否和正则表达式匹配。
正则表达式就是一些用来匹配和处理文本的字符串。
写正则表达式的过程
- 列出需求找到合适的正则
- 将正则组合为正则表达式
- 考虑异常的输入
- 需求增加
- 最后写出完整的正则表达式
字符集
在[ ]中写入想要匹配的字符,比如[10]表示匹配字符1或者字符0;[0-9]表示匹配数字0到数字9之间的一个数字。
代码 | 说明 |
---|---|
[aeiou] | 匹配元音字母 |
[0-9] | 匹配数字 |
[a-z0-9A-Z_] | 匹配字母数字和下划线 |
元字符
在[ ]中写入想要匹配的字符这种方法,有时候也会很麻烦,比如要匹配数字又要匹配字母,还要匹配下划线这些字符的时候,正则就会写成这样:[0-9a-zA-Z_],这样就加大代码的复杂度。
所以就有了元字符:
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
这里只给出了一部分元字符,更多的元字符可以自己查阅资料。
限定符号
以上都只能匹配一个字符,为了能够匹配多个字符,所以就有了对字符个数进行限定的限定符号:
代码 | 说明 |
---|---|
* | 重复零次或者多次 |
+ | 重复一次或者多次 |
? | 重复零次或者一次 |
{n} | 重复n次 |
{n,} | 重复n次或者更多次 |
{n,m} | 重复n到m次 |
例子
请写出判定QQ号码在5-12位之间的正则表达式
1、列出需求:
5-12 位 {5-12}
号码全部为数字 \d
2、组合出正则表达式
\d{5,12}
3、考虑异常输入
F15677792d 01234567
3、需求增加
前后结束的字符都应该是数字 ^\d \d$
首位不能是0 ^[1-9]
5、最后的正则表达式 ^[1-9]\d{3,10}\d$
这里面用到了 ^ 和 $ ,他们表示匹配字符串的开始位置和结束位置
代码 | 说明 |
---|---|
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
\b | 匹配单词的开始或结束 |
\B | 非单词边界匹配 |
JavaScript表述正则的方法:
直接语量法:
例如:var reg=/\d+/;
加入修饰符:var reg=/\d+/g;
使用RegExp 对象语法:
例如:var reg=new RegExp(pattern,attributes);
var reg=new RegExp("\d+","g");
pattern:输入的正则表达式;
attributes:修饰符
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止) |
m | 执行多行匹配 |
正则表达式的方法
RegExp方法
方法 | 描述 |
---|---|
compile | 编译正则表达式 |
exec | 检索字符串中指定的值。返回找到的值,并确定其位置 |
test | 检索字符串中指定的值。返回 true 或 false |
支持正则表达式的String对象
方法 | 描述 |
---|---|
search | 检索与正则表达式相匹配的值 |
match | 找到一个或多个正则表达式的匹配 |
replace | 替换与正则表达式匹配的子串 |
split | 把字符串分割为字符串数组 |
例子:
匹配一段字符串是否是正确的身份证号码
这里直接给出正则表达式:/^5103\d{13}[0-9Xx]$/ (这里的 / / 表示这段字符串是一个正则表达式)。
var str="51032220201124003x";
var re=/^5103\d{13}[0-9Xx]$/;
var res=re.test(str);
console.log(res); //true
如果想要从这段身份证号码中将出生年月日提取出来的话,改怎么做?
这个时候分组捕获就出来了
子表达式(分组):使用()将正则包起来当成一个独立元素来使用。
var str="hello my name is ben &npsb;,this is ";
var re=/( ){1,}/g;
var res=str.match(re);
提取身份证号码中的出身年月日:
var str="51032220201124003x";
var re=/(^5103\d{2})(\d{8})(\d{3}[0-9Xx]$)/;
var res=re.exec(str);
console.log(res);
使用exec()方法会返回一个数组,数组的第0个值为与正则表达式匹配的字符串,第1个值为第一个子表达式(分组)匹配的值,同理第2个值为第二个子表达式(分组)匹配的值;
groups:是对子表达式进行命名后返回的命名之后的子表达式匹配的值;
index:是第一次匹配的位置;
input:是进行匹配的字符串。
代码 | 说明 |
---|---|
(exp) | 匹配exp,并捕获文本到自动命名的组里(从1开始对分组进行命名,0是整个表达式) |
(?exp) | 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name’exp) |
(?:exp) | 匹配exp,不捕获匹配的文本,也不给此分组分配组号 |
例子:
将电话号码转换为000-0000-0000的形式
var str='12345678901';
var re=/(\d{3})(\d{4})(\d{4})/;
var res=str.replace(re,"$1-$2-$3");
console.log(res); //123-4567-8901
可以 $n来对第n个子表达式匹配到的内容进行引用
分支条件:
分枝条件:是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用 | 把不同的规则分隔开
例子:
将<img src="123.jpg"><img src="123.png"><img src="123.gif">
中所有的图片链接提取出来
var str="<img src='123.jpg'><img src='123.png'><img src='123.gif'>";
var reg=/src='(\d+\.jpg)'|src='(\d+\.png)'|src='(\d+\.gif)'/g;
var res=str.match(reg);
console.log(res);
零宽断言:
在使用正则表达式进行匹配的时候,如果要求匹配的内容的前后要满足一定的条件,比如,匹配abcing abcng 要匹配ing前面的abc,这个时候就需要用到零宽断言。
代码 | 说明 |
---|---|
(?=exp) | 匹配后面跟的是exp的位置 |
(?<=exp) | 匹配前面是exp的位置 |
(?!exp) | 匹配后面跟的不是exp的位置 |
(?<!(exp) | 匹配前面不是exp的位置 |
零宽断言匹配的都是一个位置
例子:
在数字中插入千分位
var str="价格是123456789.6754";
var reg=/(\d)(?=(\d{3})+\.)/g;
var res1=str.replace(reg,'$1,')
console.log(res1); //价格是123,456,789.6754
以上都是一些常用的正则,如有问题请各位多多指出。