js正则表达式

@(javascript)[js正则表达式]javascript

[toc]html

js正则表达式

正则表达式一直是一个使人头疼但却又是十分重要的一个东西。熟练的使用正则表达式可让你的工做事半功倍。接下来,一块儿来看看正则表达式是什么吧!java

正则表达式概念

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表一般被用来检索、替换那些符合某个模式(规则)的文本。正则表达式

正则表达式的基本语法

var reg = / pattern / flags;
复制代码

就像上面的,正则表达式是由两个/符号包裹起来的,两个/里面的(上面的pattern)就是须要的任何简单或者是复杂的正则表达式。而在第二个/后面是一个或者是多个标志(flags),用来标明正则表达式的行为。 flags有如下五种行为:数组

  • g:表示全局(global)模式,即在匹配到第一个后继续匹配
  • i:忽略(ignore)大小写
  • m:即是多行(multiline)模式,即到达一行时继续查找下一行
  • y:(ES6新增的粘连修饰符)
  • u:(ES6新增)

正则的规则分类

下面根据JavaScript正则表达式的速查表中的分类来对每一下进行一个说明。bash

正则表达式基础

基础里面呢主要有6须要记忆的东西,分别是:函数

  • .:匹配除了换行之外其余全部字符
  • a:匹配字符a,衍生为匹配单个字母
  • ab:匹配字符串ab,衍生为匹配字符串
  • a|b:匹配a或者b,就是或者的意思
  • a*:匹配一次或者是屡次a
  • \:转义符号,转义一个特殊的字符
// `.`的使用
var reg = /./g;
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // (7) ["a", "b", "c", "d", "e", "f", "g"]

// `a`的使用
var reg = /A/gi; // 全局匹配。忽略大小写
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // (7) ["a"]

// `ab`的使用
var reg = /AbCdef/gi; // 全局匹配。忽略大小写
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // (7) ["abcdef"]

// `a|b`的使用 一
var reg = /a|b|c|d/; // 非全局匹配。
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // ["a", index: 0, input: "abcdefg"]

// `a|b`的使用 二
var reg = /a|b|c|d/g; // 全局匹配。
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // (4) ["a", "b", "c", "d"]。使用全局匹配。会在匹配对后继续匹配

// `a*`的使用
var reg = /a*/; 
var text = "abcdcba";
var res = text.match(reg);
console.log(res); // ["a", index: 0, input: "abcdcba"]

// `a*`的使用
var reg = /a*/g; // 全局匹配。
var text = "abcdcba";
var res = text.match(reg);
console.log(res); // (8) ["a", "", "", "", "", "", "a", ""]。使用全局匹配会把以后没有匹配到的转化为空字符串

// `\`的使用 回到第一个 . 的使用那里。若是我把 . 前面加一个 \ 符号,那么这个点就是一个普通的点了
var reg = /\./g; // 全局匹配。
var text = "abcdefg";
var res = text.match(reg);
console.log(res); // null
复制代码

JavaScript中须要使用 \ 的特殊符号有:( ) [ ] { } . | + * ? \ ^ $ 以及 空白测试

正则表达式字符类

  • [ab-d]:a,b,c,d四个字符中的一个,衍生为使用[],那就是匹配其中的一个
  • [^ab-d]:除了a,b,c,d四个字符其余的任意字符,衍生为使用[^]能够排除[]里面的东西
  • [\b]:退格字符,了解
  • \d:一个0-9的数字
  • \D:一个非数字
  • \s:一个空白字符
  • \S:一个非空白字符
  • \w:匹配一个字母,数字或者是下划线
  • \W:匹配一个除字母,数字,下划线以外的任意字符
// `[a-z]`的使用
var reg = /[a-z]/g; // 全局匹配。匹配 a-z 的任意一个,由于是全局匹配。因此会一直找。可是不会有 1234
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (4) ["a", "b", "c", "d"]

// `[a-z]`的使用
var reg = /[^a-z]/g; // 全局匹配。匹配 除了 a-z 的任意一个。因此是 1 2 3 4。由于是全局匹配。因此会一直找
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (4) ["1", "2", "3", "4"]

// `[\b]`的使用
var reg = /[\b]/g; // 全局匹配。匹配 \b,固然也能够匹配其余的特殊转义字符,见 正则表达式特殊字符
var text = "abcd\b1234";
var res = text.match(reg);
console.log(res); // (4) ["1", "2", "3", "4"]

// `\d`,`\D`,`\s`,`\S`,`\w`,`\W`的使用
var reg = /\D\d/g; // 全局匹配。匹配一个非数字与一个数字。二者紧靠在一块儿 注意顺序
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["d1"]
// 若是是下面的一个,则匹配 null
var reg = /\D\d/g; // 全局匹配。匹配一个数字与一个非数字。二者紧靠在一块儿 注意顺序
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // null
// 匹配一个
var reg = /\D\s\w\d/g; // 全局匹配。注意顺序 注意大小写
var text1 = "abcd1234";
var text2 = "abcd _1234";
var res1 = text1.match(reg);
var res2 = text2.match(reg);
console.log(res1); // null
console.log(res2); // ["d _1"]
复制代码

正则表达式量词

  • *:匹配0次或者屡次。等价于{0,}
  • +:匹配一次或者屡次。等价于{1,}
  • ?:匹配0次或者一次。等价于{0,1}
  • {2}:只匹配2
  • {2, 5}:匹配2-5
  • {2,}:匹配2次或者屡次

这里涉及到一个贪婪匹配非贪婪匹配贪婪匹配指的是使用以上量词的时候会按照最大次数进行匹配。 非贪婪匹配则是按最小次数进行匹配。ui

使用非贪婪匹配只需在两次后面加上一个?spa

// `*`的使用
// 非全局匹配。
var reg = /[a-z]*/; // 匹配 a-z 的0个或者多个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["abcd", index: 0, input: "abcd1234"]
// 全局匹配。
var reg = /[a-z]*/g; // 匹配 a-z 的0个或者多个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (6) ["abcd", "", "", "", "", ""]。当匹配为 0 个的时候,会变成空字符串。对比 + 号

// `+`的使用
// 非全局匹配。
var reg = /[a-z]+/; // 匹配 a-z 的0个或者多个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["abcd", index: 0, input: "abcd1234"]
// 全局匹配。
var reg = /[a-z]+/g; // 匹配 a-z 的0个或者多
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["abcd"]。由于至少匹配一个,因此不会有空字符串。对比 * 号

// `?`的使用
// 非全局匹配。
var reg = /[a-z]?/; // 匹配 a-z 的0个或者一个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["a", index: 0, input: "abcd1234"]。匹配到一个就停下来
// 全局匹配。
var reg = /[a-z]?/g; // 匹配 a-z 的0个或者一个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["a", "b", "c", "d", "", "", "", "", ""]。abcd匹配到了。1234则是空字符串。
复制代码

以上说的都属于贪婪匹配。都是按最多个匹配的。若是是非贪婪匹配。则是按照最少的次数匹配。

// `*`的使用
// 非全局匹配。贪婪匹配
var reg = /[a-z]*/; // 匹配 a-z 的0个或者多个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["abcd", index: 0, input: "abcd1234"]
// 全局匹配。贪婪匹配
var reg = /[a-z]*/g; // 匹配 a-z 的0个或者多个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (6) ["abcd", "", "", "", "", ""]。当匹配为 0 个的时候,会变成空字符串。对比 + 号

// 非全局匹配。非贪婪匹配
var reg = /[a-z]*?/; // 匹配 a-z 的0个或者多个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // ["", index: 0, input: "abcd1234"]
// 全局匹配。非贪婪匹配
var reg = /[a-z]*?/g; // 匹配 a-z 的0个或者多个
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (9) ["", "", "", "", "", "", "", "", ""]
复制代码

以上就是贪婪匹配非贪婪匹配的区别。不过不论是如何。在匹配是0次的时候。空字符串的个数老是匹配不成功部分的字符串的长度+1

正则表达式捕获组与非捕获组

  • (...):捕获组
  • (?...):非捕获组
  • \Y:匹配第Y个被捕获的组(也称反向引用)。其中Y是一个数字,这个数组取值范围是*,即{0,}。可是建议反向引用不要索引大于9的捕获性分组。
捕获组
var reg = /ab(cd(1234))/;
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (3) ["abcd1234", "cd1234", "1234", index: 0, input: "abcd1234"]
复制代码

分析:

  1. 捕获组就是在匹配 ()外面的字符以后在匹配 () 里面的。结果中的 "abcd1234"
  2. 捕获组里面还有捕获组会先忽略里面的捕获组匹配在一次匹配里面的捕获组。结果中的"cd1234""1234"
非捕获组
var reg = /ab(?:cd(1234))/;
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (3) ["abcd1234", "1234", index: 0, input: "abcd1234"]
复制代码

分析:非捕获组就是不捕获,就行上面的结果中没有了"cd1234"

那么捕获与非捕获有什么区别呢? 记得看宠物小精灵的时候小智看见新的小精灵扔球抓小精灵的时候就属于一个捕获,若是看见不扔球那就是不捕获。那捕获和不捕获有什么区别呢?就行抓小精灵同样,抓住了以后就能够用了嘛!因此被捕获的东西以后是可使用的。那么怎么使用呢? 问得好。这时候就须要使用到\Y 了。

var reg1 = /(a)/;
var reg2 = /(a)\1/; // 至关因而 /(a)a/
var text1 = "aabb1234";
var text2 = "aabb1234";
var res1 = text1.match(reg1);
var res2 = text2.match(reg2);
console.log(res1); // ["a", "a", index: 0, input: "aabb1234"]
console.log(res2); // ["aa", "a", index: 0, input: "aabb1234"]
复制代码

上面的例子中,reg1reg2 仅仅有一点不一样。可是匹配后的东西是不一样的。简单地说,就是,使用 \Y 后会赋值第Y个捕获的组。如下代码说明经过$Y来接收相应的捕获组。不能从0开始

\Y
var reg = /ab(cd(1234))/;
var text = "abcd1234";
var res = text.match(reg);
console.log(res); // (3) ["abcd1234", "cd1234", "1234", index: 0, input: "abcd1234"]
console.log(RegExp.$0); // undefined
console.log(RegExp.$1); // cd1234
console.log(RegExp.$2); // 1234
var res1 = text.replace(reg,"$1$2"); // 使用 $1 $2 取出捕获组的内容
console.log(res1); // cd12341234
复制代码

正则表达式断言

  • ^:字符串的开始必须是
  • $:字符串的结尾必须是
  • \b:匹配文字(单词)边界
  • \B:非文字(单词)边界
  • (?=...):积极的前瞻(也叫前瞻或者是顺序确定环视)
  • (?!...):消极的前瞻(也加后瞻或者是顺序否认环视)
^$的使用
var reg = /^b.*\d$/; // 要求字符 b 开头,中间 * 个任意字符(除换行符),必须以数字结束
var text1 = "abcd1234";
var text2 = "bcd";
var text3 = "bcd1234";
var res1 = text1.match(reg);
var res2 = text2.match(reg);
var res3 = text3.match(reg);
console.log(res1); // null
console.log(res2); // null
console.log(res3); // ["bcd1234", index: 0, input: "bcd1234"]
复制代码
\b\B的使用
var reg = /\bhi\b/; // 
var text1 = "hi"; 
var text2 = "him"; 
var text3 = "history";
var res1 = text1.match(reg);
var res2 = text2.match(reg);
var res3 = text3.match(reg);
console.log(res1); // ["hi", index: 0, input: "hi"]
console.log(res2); // null
console.log(res3); // null
复制代码
积极的前瞻 (?=...) 积极的前瞻 匹配后面是 ... 的位置,不捕获匹配结果
var reg = /abcd(?=1234)/;
var text = "abcd1234";
var text1 = "abcdefg";
var res = text.match(reg);
var res1 = text1.match(reg);
console.log(res) // ["abcd", index: 0, input: "abcd1234"]
console.log(res1) // null
复制代码

看上面的例子能够看出积极的前瞻匹配1234前面的abcd,不匹配def前面的abcd;而消极的前瞻偏偏相反,看下面的例子。

消极的前瞻 (?!...) 消极的前瞻 匹配后面不是 ... 的位置,不捕获匹配结果
var reg = /abcd(?!=1234)/;
var text = "abcd1234";
var text1 = "abcdefg";
var res = text.match(reg);
var res1 = text1.match(reg);
console.log(res) // null
console.log(res1) // ["abcd", index: 0, input: "abcd1234"]
复制代码

正则表达式特殊字符

  • \n:换行符
  • \r:回车符
  • \t:制表符
  • \0:空字符
  • \YYY:8进制字符
  • \xYY:十六进制字符
  • \uYYYY:十六进制字符
  • \cY:控制符 正则的特殊字符在实际中运用的比较少,具体的用法与以前讲到的[\b]相似。上面的两个十六进制字符中,\xYY主要匹配数字字母等。而\uYYYY则是为了匹配汉字以及如下特殊的符号。

正则表达式替换

正则表达式替换主要是替换一些字符。主要如下几个,但是在replace中使用。

  • $$:插入$
  • $&:插入整个匹配
  • $`:插入匹配项前面的字符串
  • $':插入匹配项后面的字符串
  • $Y:插入第Y个捕获的组
var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var res = text.match(reg);
console.log(res); // (2) ["淡如水,", ",", index: 4, input: "君子之交淡如水,小人之交甘若醴"]
复制代码
$$:插入$
var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$$");
console.log(newStr); // 君子之交$小人之交甘若醴
复制代码
$&:插入整个匹配
var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$&");
console.log(newStr); // 君子之交淡如水,小人之交甘若醴
复制代码
$`:插入匹配项前面的字符串
var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$`");
console.log(newStr); // 君子之交君子之交小人之交甘若醴
复制代码
$':插入匹配项后面的字符串
var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$'");
console.log(newStr); // 君子之交小人之交甘若醴小人之交甘若醴
复制代码
$Y:插入第Y个捕获的组
var reg = /.{2}水(.)/;
var text = "君子之交淡如水,小人之交甘若醴";
var newStr = text.replace(reg,"$1");
console.log(newStr); // 君子之交,小人之交甘若醴
复制代码

正则表达式实例的方法

exec() 最主要的方法

此方法专门为捕获组设计的。此方法接收一个参数,及须要测试的字符串。返回数组或者是null。但返回的值包含两个额外的属性: index:匹配性在字符串中的位置 input:应用正则的表达式

var reg = /你(我他(与她))/
var text = "你我他与她";
var res = reg.exec(text);
console.log(res); //(3) ["你我他与她", "我他与她", "与她", index: 0, input: "你我他与她"]
复制代码

["你我他与她", "我他与她", "与她", index: 0, input: "你我他与她"]的结果。使用res[下标]能够查看具体的匹配下。从第二项开始才是捕获项。使用res.indexres.input查看起始位置与匹配的字符串。

exec()方法始终返回一项,若是设置了全局匹配g,只会从上一次结束的敌法继续查找,而不会返回多项。

var text = "bat, cat, fat";

var reg1 = /.at/;
var res = reg1.exec(text);
console.log(res.index);	// 0
console.log(res[0]);	// bat

var res = reg1.exec(text);
console.log(res.index);	// 0
console.log(res[0]);	// bat

var reg2 = /.at/g;

var res = reg2.exec(text);
console.log(res.index);	// 0
console.log(res[0]);	// bat

var res = reg2.exec(text);
console.log(res.index);	// 5
console.log(res[0]);	// cat
复制代码

test()方法

接收一个字符串做为参数,返回: true:匹配 false:不匹配

var text = "abcd1234";
var reg1 = /\D/g;
var reg2 = /\s/g;
var res1 = reg1.test(text);
console.log(res1);	// true
var res2 = reg2.test(text);
console.log(res2);	// false
复制代码

关于使用RegExp构造函数

语法:var reg = new RegExp(参数1[,参数2]);

var reg = new RegExp("\D","gi");
var text = "ABd1234";
var res = reg.exec(text);
console.log(res); // ["d", index: 2, input: "ABd1234"]
复制代码

看上面的例子。两个参数须要使用字符串。 可是,上面的例子有一个问题。没有按照咱们所想的出现一个A,而是一个d。同时,咱们忽略大小写在看一下:

var reg = new RegExp("\D","g");
var text = "ABd1234";
var res = reg.exec(text);
console.log(res); // null
复制代码

因此,使用构造函数还有一个须要注意的就是全部的元字符都须要双重转义。将上面的代码换为下面的看看

var reg = new RegExp("\\D","g");
var text = "ABd1234";
var res = reg.exec(text);
console.log(res); // ["A", index: 0, input: "ABd1234"]
复制代码

注意上面的\\D。这个才表示一个元字符。刚刚的就是一个\一个D。因此。在正则的构造函数中使用元字符须要双重转义

附上几个经常使用的正则匹配

电话号码匹配:/^1[3-8]\d{9}$/ 电子邮件:/[a-zA-z0-9_-]{6,12}@[a-zA-z0-9_-]+\.[a-zA-z0-9]+/ 匹配特定了的邮件:/[a-zA-z0-9_-]{6,12}@(163|qq|gmail)\.com/

更多的匹配可查阅:最全的经常使用正则表达式大全

以上就是关于正则的一些使用概念以及使用方法。若是想要熟练的使用正则去匹配或者是修改字符串。仍是须要不断的练习才是。

相关文章
相关标签/搜索