# 正则表达式
RegExp 对象用于将文本与一个模式匹配。
有两种方法可以创建一个 RegExp 对象:一种是字面量,另一种是构造函数。
var re = /ab+c/ig; // 字面量
var re = new RegExp('ab+c', 'ig'); // 构造函数,遇到特殊字符要多转义一遍
var re = new RegExp(/ab+c/, 'ig'); // 构造函数
i
表示忽略大小写,g
表示全局查找
当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。
var re = new RegExp("\\w+");
var re = /\w+/;
# 实例常用方法
re.exec(str)
使用正则规则匹配字符串str,返回一个数组或 null。
TIP
常用与匹配特殊格式里的字符串,并返回此字符串,如 [xxxx]
返回括号里的字符。
获取URL中的域名或者当前路由。
var str = 'changzhen hello china!'
var reg = /a/;
var matches = reg.exec(str);
console.log(matches[0]) // a
re.test(str)
判断正则表达式与指定的字符串是否匹配。返回 true 或 false。
TIP
判断字符串是否包含某个字符等。
var str = 'hello world!';
var re = /hello/;
var result = re.test(str);
console.log(result); // true
字符串方法 match
replace
search
都可以接收正则来进行匹配
str.match(val)/str.match(regexp) // 检索返回匹配到值的数组
'h1h2h3'.match(/\d+/g) // ["1", "2", "3"]
str.replace(regexp/substr, replacement) // 以replacement替换匹配到的正则或字符串
'xxxhxxh'.replace('h', 'g') // "xxxgxxh" 字符串只匹配第一个
'xxxhxxHxx'.replace(/h/ig, 'g') // "xxxgxxgxx" 全局匹配
// $& $1 $2 $n 代表匹配到的第一个和第二个括号的子字符串匹配。
var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr); // 'Smith, John'
str.search(val/regexp) // 返回第一个匹配到的字符串的起始位置,没有返回-1 和indexOf类似
# 正则表达式中的特殊字符
^
匹配输入的开始,以某一个匹配符开头开始匹配,如果开头就不匹配就返回false
var str = 'hello world!'
var reg = /^o/; // 是否以o开头匹配
var reg2 = /^h/;
var reg3 = /^[A-Za-z]/;
var reg4 = /^[0-9]/;
console.log(reg.test(str)) // false
console.log(reg2.test(str)) // true
console.log(reg3.test(str)) // true
console.log(reg4.test(str)) // false
$
// 匹配输入的结束,以某一个匹配符为结束,如果不是以这个匹配符结束的就返回false
var str = 'hello world!'
var reg2 = /!$/; // 是否以!为结束的匹配
var reg3 = /^[a-z].+!$/; // 以小写字母开头,中间是多个任意字符,以!为结束的正则
console.log(reg.test(str)) // false
console.log(reg2.test(str)) // true
console.log(reg3.test(str)) // true
^
和 $
一起使用,表示字符串开始就要匹配这个规则,然后结尾字符串也要匹配这个规则,不能从某一段字符串匹配。
var str = '1how are you, hello world!'
var reg = /^[0-9].+!$/; // 以数字开始匹配到!结束
console.log(reg.test(str)) // true
// 匹配邮箱
var emil = '1979250385@qq.com'
var reg2 = /^\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/ig;
console.log(reg2.test(emil)) // true
\
转义字符串,如要匹配特殊字符 '/' ,使用字面量写法时要使用转义字符 \
对特殊字符 '/' 转义一下,如果使用字符串写法就要多转义一遍才行。
var str = 'C:/root';
var str2 = 'xxx xxx';
var reg = /^[A-Z]:\// // 匹配C:/
var reg2 = new RegExp(/^[A-Z]:\//,'i') // 这种和字面量一样转义一遍。
var reg3 = new RegExp('[a-z]:\\\/','i') // 这种要多转义一遍
// 使用构造器创建正则时要把转义字符和匹配字符都要转义一遍才行。
// \\\/ --> \\ + \/ --> \/ --> /
console.log(reg.test(str)) // true
console.log(reg2.test(str)) // true
console.log(reg3.test(str)) // true
备选字符集
[]
表示匹配某些可能出现的字符,每一个字符都可能被匹配,但只能从其中匹配一个,如果是连续的可以用 -
省略。
[0-9] --> 匹配0-9中的任意一个
[a-z] --> 匹配a-z中的任意一个
[A-Z] --> 匹配A-Z中的任意一个
[0-9a-zA-Z] --> 数字字母中的任意一个
[xyz] --> xyz中的任意一个
[^xyz] --> 除xyz中的任意一个字符
x|y --> 匹配 x 或者 y 。
var str = '你好啊,你在哪呢0,草'
var reg = /[草]/
var reg2 = /[0-9a-zA-Z]/
console.log(reg.test(str)) // true
console.log(reg2.test(str)) // true
预定义备选字符集
\d [0-9] 匹配一个数字
\D [^0-9] 和\d相反,匹配除[0-9] 之外的
\w [0-9a-zA-Z_] 大小写字母、数字和 _
\W [^0-9a-zA-Z_] 大小写字母、数字和 _ 除外的字符
\s 一位空字符 空格 tab (回车换行不行)
\S 一个非空字符
. 一个任意字符 回车换行\n除外
正则表达式的量词
规定量词前面的这个字符集出现的次数
第一种确定次数 {}
{n} 匹配了前面一个字符出现了 n 次
{n, } 匹配前一个字符至少出现了n次
{n, m} 匹配前面的字符至少n次,最多m次
第二种不确定性
* 0个或者多个 (没有或者有){0, }
+ 1个或者多个 (至少1个){1, }
? 0个或者1个 (没有或者只有一个) {0, 1}
var str1 = 'changzhen154';
var str2 = '254653';
var reg1 = /^[a-zA-Z0-9]{6,16}$/ // 匹配6-16位密码
var reg2 = /^[0-9]{6}$/ // 匹配6位验证码
console.log(reg1.test(str1)) // true
console.log(reg2.test(str2)) // true
分组和捕获
()
分组:主要作用:要某些字符作为一个整体,控制这个整体出现的次数。分组可以分为两种形式,捕获组和非捕获组。
// abc 三个字符出现0次或者多次
(abc)*
// 手机号前面可以是 0086 或者10086 且只能出现一次
(0086|10086)?\s[1]\d{10}
非捕获 (?:x)
不记住 不能使用\n 来替换使用
捕获 (X)
就是用\n 来记住分组,然后接着使用。
像下面分组 (foo) (bar) 会匹配到字符串 'foo' 'bar' 并会记住这两个字符串。匹配中的 \1 和 \2 表示第一个和第二个被捕获括号匹配的子字符串,即 foo 和 bar,匹配了原字符串中的后两个单词。可以用\1 和\2 来替代了,就行replace中的 $1,$2。
//
var str = 'foo bar foo bar'
var reg = /(foo) (bar) \1 \2/ // /(foo) (bar) (foo) (bar)/
console.log(reg.test(str)) // true
str.replace(/(foo) (bar)/, '$1 $2') // "foo bar foo bar"
x(?=y)
匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言。
例如,/Jack(?=Sprat)/会匹配到'Jack'仅当它后面跟着'Sprat'。/Jack(?=Sprat|Frost)/匹配‘Jack’仅当它后面跟着'Sprat'或者是‘Frost’。但是‘Sprat’和‘Frost’都不是匹配结果的一部分。
(?<=y)x
匹配'x'仅当'x'前面是'y'.这种叫做后行断言。
例如,/(?<=Jack)Sprat/会匹配到' Sprat '仅仅当它前面是' Jack '。/(?<=Jack|Tom)Sprat/匹配‘ Sprat ’仅仅当它前面是'Jack'或者是‘Tom’。但是‘Jack’和‘Tom’都不是匹配结果的一部分。
x(?!y)
仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找。
例如,仅仅当这个数字后面没有跟小数点的时候,/\d+(?!.)/ 匹配一个数字。正则表达式/\d+(?!.)/.exec("3.141")匹配‘141’而不是‘3.141’
(?<!y)x
仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找。
例如, 仅仅当这个数字前面没有负号的时候,/(?<!-)\d+/ 匹配一个数字。
/(?<!-)\d+/.exec('3') // 匹配到 "3".
/(?<!-)\d+/.exec('-3') // 因为这个数字前有负号,所以没有匹配到。