正则表达式非常有用, 查找, 匹配, 处理字符串, 替换和转换字符串, 输入输出等. 下面整理一些常用的正则表达式.
常用的正则字符
1.\ : 将下一个字符标记为一个特殊字符, 或一个原义字符, 或一个 向后引用, 或一个八进制转义符. 例如,'n' 匹配字符 "n".'n' 匹配一个换行符. 序列 '\' 匹配 ""而"("则匹配"(".
2.^: 匹配输入字符串的开始位置. 如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配'n' 或'r' 之后的位置.
3.$: 匹配输入字符串的结束位置. 如果设置了 RegExp 对象的 Multiline 属性,$ 也匹配'n' 或'r' 之前的位置.
4.*: 匹配前面的子表达式零次或多次. 例如, zo 能匹配 "z" 以及 "zoo". 等价于{0,}.
5.+: 匹配前面的子表达式一次或多次. 例如,'zo+' 能匹配 "zo" 以及 "zoo", 但不能匹配 "z".+ 等价于 {1,}.
6.?: 匹配前面的子表达式零次或一次. 例如,"do(es)?" 可以匹配 "do" 或 "does" 中的 "do" .? 等价于 {0,1}.
7.{n}:n 是一个非负整数. 匹配确定的 n 次. 例如,'o{2}' 不能匹配 "Bob" 中的'o', 但是能匹配 "food" 中的两个 o.
8.{n,}:n 是一个非负整数. 至少匹配 n 次. 例如,'o{2,}' 不能匹配 "Bob" 中的'o', 但能匹配 "foooood" 中的所有 o.'o{1,}' 等价于'o+'.'o{0,}' 则等价于'o*'.
9.{n,m}:m 和 n 均为非负整数, 其中 n <= m. 最少匹配 n 次且最多匹配 m 次. 例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o.'o{0,1}' 等价于'o?'. 请注意在逗号和两个数之间不能有空格.
10.?: 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时, 匹配模式是非贪婪的. 非贪婪模式尽可能少的匹配所搜索的字符串, 而默认的贪婪模式则尽可能多的匹配所搜索的字符串. 例如, 对于字符串 "oooo",'o+?' 将匹配单个 "o", 而'o+' 将匹配所有'o'.
11..: 匹配除 "n" 之外的任何单个字符. 要匹配包括'n' 在内的任何字符, 请使用象 '[.n]' 的模式.
12.(pattern): 匹配 pattern 并获取这一匹配. 所获取的匹配可以从产生的 Matches 集合得到, 在 VBScript 中使用 SubMatches 集合, 在 JScript 中则使用 $0...$9 属性. 要匹配圆括号字符, 请使用 '(' 或 ')'.
13.(?:pattern): 匹配 pattern 但不获取匹配结果, 也就是说这是一个非获取匹配, 不进行存储供以后使用. 这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用. 例如, 'industr(?:y|ies) 就是一个比'industry|industries' 更简略的表达式.
14.(?=pattern): 正向预查, 在任何匹配 pattern 的字符串开始处匹配查找字符串. 这是一个非获取匹配, 也就是说, 该匹配不需要获取供以后使用. 例如,'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" , 但不能匹配 "Windows 3.1" 中的 "Windows". 预查不消耗字符, 也就是说, 在一个匹配发生后, 在最后一次匹配之后立即开始下一次匹配的搜索, 而不是从包含预查的字符之后开始.
15.(?!pattern): 负向预查, 在任何不匹配 pattern 的字符串开始处匹配查找字符串. 这是一个非获取匹配, 也就是说, 该匹配不需要获取供以后使用. 例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows", 但不能匹配 "Windows 2000" 中的 "Windows". 预查不消耗字符, 也就是说, 在一个匹配发生后, 在最后一次匹配之后立即开始下一次匹配的搜索, 而不是从包含预查的字符之后开始
16.x|y: 匹配 x 或 y. 例如,'z|food' 能匹配 "z" 或 "food".'(z|f)ood' 则匹配 "zood" 或 "food".
17.[xyz]: 字符集合. 匹配所包含的任意一个字符. 例如, '[abc]' 可以匹配 "plain" 中的'a'.
18.[^xyz]: 负值字符集合. 匹配未包含的任意字符. 例如, '1' 可以匹配 "plain" 中的'p'.
19.[a-z]: 字符范围. 匹配指定范围内的任意字符. 例如,'[a-z]' 可以匹配'a' 到'z' 范围内的任意小写字母字符.
20.[^a-z]: 负值字符范围. 匹配任何不在指定范围内的任意字符. 例如,'2' 可以匹配任何不在'a' 到'z' 范围内的任意字符.
21.\b: 匹配一个单词边界, 也就是指单词和空格间的位置. 例如, 'erb' 可以匹配 "never" 中的'er', 但不能匹配 "verb" 中的'er'.
22.\B: 匹配非单词边界.'erB' 能匹配 "verb" 中的'er', 但不能匹配 "never" 中的'er'.
23.\cx: 匹配由 x 指明的控制字符. 例如, cM 匹配一个 Control-M 或回车符. x 的值必须为 A-Z 或 a-z 之一. 否则, 将 c 视为一个原义的'c' 字符.
24.\d: 匹配一个数字字符. 等价于 [0-9].
25.\D: 匹配一个非数字字符. 等价于 3.
26.\f: 匹配一个换页符. 等价于 x0c 和 cL.
27.\n: 匹配一个换行符. 等价于 x0a 和 cJ.
28.\r: 匹配一个回车符. 等价于 x0d 和 cM.
29.\s: 匹配任何空白字符, 包括空格, 制表符, 换页符等等. 等价于 [ fnrtv].
30.\S: 匹配任何非空白字符. 等价于 4.
31.\t: 匹配一个制表符. 等价于 x09 和 cI.
32.\v: 匹配一个垂直制表符. 等价于 x0b 和 cK.
33.\w: 匹配包括下划线的任何单词字符. 等价于'[A-Za-z0-9_]'.
34.\W: 匹配任何非单词字符. 等价于 '5'.
35.\xn: 匹配 n, 其中 n 为十六进制转义值. 十六进制转义值必须为确定的两个数字长. 例如,'x41' 匹配 "A".'x041' 则等价于'x04' & "1". 正则表达式中可以使用 ASCII 编码.
36.\num: 匹配 num, 其中 num 是一个正整数. 对所获取的匹配的引用. 例如,'(.)1' 匹配两个连续的相同字符.
37.\n: 标识一个八进制转义值或一个向后引用. 如果 n 之前至少 n 个获取的子表达式, 则 n 为向后引用. 否则, 如果 n 为八进制数字 (0-7), 则 n 为一个八进制转义值.
38.\nm: 标识一个八进制转义值或一个向后引用. 如果 nm 之前至少有 nm 个获得子表达式, 则 nm 为向后引用. 如果 nm 之前至少有 n 个获取, 则 n 为一个后跟文字 m 的向后引用. 如果前面的条件都不满足, 若 n 和 m 均为八进制数字 (0-7), 则 nm 将匹配八进制转义值 nm.
39.\nml: 如果 n 为八进制数字 (0-3), 且 m 和 l 均为八进制数字 (0-7), 则匹配八进制转义值 nml.
RegExp 类型
ECMAScript 通过 RegExp 类型支持正则表达式, 如下:
var expression = /pattern/flags;
其中的模式 (pattern) 部分可以是任何简单或者复杂的正则表达式, 可以包含字符类, 限定符, 分组, 向前查找以及反向引用. 每个正则表达式可带有一个或者多个标注(flags), 用以标明正则表达式的行为. 有三个一下标志:
g: 表示全局模式, 即模式将被应用到所有字符串, 而非在发现第一个匹配项时立即停止.
i: 表示不区分大小写模式.
m: 表示多行模式, 即在到达一行文本末尾时还在继续查找下一行中是否存在于模式匹配的项.
正则表达式定义方式
以字面量的形式来定义正则表达式
例如: 匹配第一个 bat 或者 cat, 不区分大小写
var pattern = /[bc]at/i;
使用 RegExp 构造函数
它接收两个参数: 一个是要匹配的字符串模式, 另一个是可选的标志字符串. 可以使用字面量定义的任何表达式, 都可以使用构造函数来定义, 还是以上面的例子为例:
var pattern = new RegExp("[bc]at","i");
注意: RegExp 构造函数模式参数时字符串, 所以再某些情况下要对字符进项双重转义. 所有元字符都必须双重转义, 如字面量模式为 /\[bc\]at/, 那么等价的字符串为 "/\\[bc\\]at/"
例子:
- var re = null,
- i;
- for(i=0; i <10; i++){
- re = /cat/g;
- console.log(re.test("catastrophe"));
- }
- for(i=0; i < 10; i++){
- re = new RegExp("cat","g");
- console.log(re.test("catastrophe"));
- }
打印结果都为 10 个 true
正则表达式方法
RegExp 对象的 exec()方法
该方法是专门为捕获组而设计的, 其接受一个参数, 即要应用模式的字符串, 然后返回包含第一个匹配项信息的数组; 或者在没有匹配项的情况下返回 null. 返回的数组虽然是 Array 的实例, 但是包含两个额外的属性: index 和 input. 其中 index 表示匹配项在字符串中的位置, 而 input 表示应用字符串表达式的字符串.
例:
- var text = "mom and dad and baby";
- var pattern = /mom( and dad( and baby)?)?/gi;
- var matches = pattern.exec(text);
- console.log(matches.index); //0
- console.log(matches.input); //mom and dad and baby
- console.log(matches[0]); //mom and dad and baby
- console.log(matches[1]); //and dad and baby
- console.log(matches[2]); //and baby
对于 exec()方法而言, 即使在模式中设置了全局标志 g, 它每次也只是返回一个匹配项. 在不设置全局标志的情况下, 在同一个字符串上多次调用 exec()方法将始终返回第一个匹配项的信息. 而在设置全局标志的情况下, 每次调用 exec()则都会在字符串中继续查找新匹配项, 如下例子:
- var text = "cat, bat, sat, fat";
- var pattern1 = /.at/;
- var matches = pattern1.exec(text);
- console.log(matches.index); //0
- console.log(matches[0]); //cat
- console.log(pattern1.lastIndex); //0
- matches = pattern1.exec(text);
- console.log(matches.index); //0
- console.log(matches[0]); //cat
- console.log(pattern1.lastIndex); //0
- var pattern2 = /.at/g;
- var matches = pattern2.exec(text);
- console.log(matches.index); //0
- console.log(matches[0]); //cat
- console.log(pattern2.lastIndex); //3
- var matches = pattern2.exec(text);
- console.log(matches.index); //5
- console.log(matches[0]); //bat
- console.log(pattern2.lastIndex); //8
注意: IE 的 JavaScript 实现 lastIndex 属性上存在偏差, 即使在非全局模式下, lastIndex 属性每次也都在变化.
test()方法
正则表达式常用方法 test(), 它接受一个字符串参数. 在模式与该参数匹配的情况下返回 true, 否则返回 false.
用法: 正则. test(字符串)
例 1: 判断是否是数字
- var str = '374829348791';
- var re = /\D/; // \D 代表非数字
- if( re.test(str) ){ // 返回 true, 代表在字符串中找到了非数字.
- alert('不全是数字');
- }else{
- alert('全是数字');
- }
例 2:
- var text ="000-00-0000";
- var pattern = /\d{3}-\d{2}-\d{4}/;
- if(pattern.test(text)){
- console.log('the pattern was matched.');
- }
search()方法
在字符串搜索符合正则的内容, 搜索到就返回出现的位置(从 0 开始, 如果匹配的不只是一个字母, 那只会返回第一个字母的位置), 如果搜索失败就返回 -1
用法: 字符串. search(正则)
例子: 在字符串中找字母 b, 且不区分大小写
- var str = 'abcdef';
- var re = /B/i;
- //var re = new RegExp('B','i'); 也可以这样写
- alert( str.search(re) ); // 1
match 方法
获取正则匹配到的结果, 以数组的形式返回
用法: 字符串. match(正则)
例如:
"186a619b28".match(/\d+/g); // ["186","619","28"]
如果上面的匹配不是全局匹配, 那么得到的结果如下:
["186", index: 0, input: "186a619b28"]
replace 方法
replace 本身是 JavaScript 字符串对象的一个方法, 它允许接收两个参数:
replace([RegExp|String],[String|Function])
第 1 个参数可以是一个普通的字符串或是一个正则表达式.
第 2 个参数可以是一个普通的字符串或是一个回调函数.
如果第 2 个参数是回调函数, 每匹配到一个结果就回调一次, 每次回调都会传递以下参数:
result: 本次匹配到的结果
$1,...$9: 正则表达式中有几个 (), 就会传递几个参数,$1~$9 分别代表本次匹配中每个() 提取的结果, 最多 9 个
offset: 记录本次匹配的开始位置
source: 接受匹配的原始字符串
以下是 replace 和 JS 正则搭配使用的几个常见经典案例:
(1)实现字符串的 trim 函数, 去除字符串两边的空格
- String.prototype.trim = function(){
- // 方式一: 将匹配到的每一个结果都用 "" 替换
- return this.replace(/(^\s+)|(\s+$)/g,function(){
- return "";
- });
- // 方式二: 和方式一的原理相同
- return this.replace(/(^\s+)|(\s+$)/g,'');
- };
^s+ 表示以空格开头的连续空白字符, s+$ 表示以空格结尾的连续空白字符, 加上() 就是将匹配到的结果提取出来, 由于是 | 的关系, 因此这个表达式最多会 match 到两个结果集, 然后执行两次替换:
- String.prototype.trim = function(){
- /**
- * @param rs: 匹配结果
- * @param $1: 第 1 个 () 提取结果
- * @param $2: 第 2 个 () 提取结果
- * @param offset: 匹配开始位置
- * @param source: 原始字符串
- */
- this.replace(/(^\s+)|(\s+$)/g,function(rs,$1,$2,offset,source){
- //arguments 中的每个元素对应一个参数
- console.log(arguments);
- });
- };
- "abcd".trim();
输出结果:
- [""," ", undefined, 0," abcd "] // 第 1 次匹配结果
- ["", undefined," ", 5," abcd "] // 第 2 次匹配结果
(2)提取浏览器 url 中的参数名和参数值, 生成一个 key/value 的对象
- function getUrlParamObj(){
- var obj = {};
- // 获取 url 的参数部分
- var params = Windows.location.search.substr(1);
- //[^&=]+ 表示不含 & 或 = 的连续字符, 加上 () 就是提取对应字符串
- params.replace(/([^&=]+)=([^&=]*)/gi,function(rs,$1,$2){
- obj[$1] = $2;
- });
- return obj;
- }
/([^&=]+)=([^&=]*)/gi 每次匹配到的都是一个完整 key/value, 形如 xxxx=xxx, 每当匹配到一个这样的结果时就执行回调, 并传递匹配到的 key 和 value, 对应到 $1 和 $2
(3)在字符串指定位置插入新字符串
- String.prototype.insetAt = function(str,offset){
- // 使用 RegExp()构造函数创建正则表达式
- var regx = new RegExp("(.{"+offset+"})");
- return this.replace(regx,"$1"+str);
- };
- "abcd".insetAt('xyz',2); // 在 b 和 c 之间插入 xyz
- // 结果 "abxyzcd"
当 offset=2 时, 正则表达式为:(^.{2}) . 表示除 \ n 之外的任意字符, 后面加 {2} 就是匹配以数字或字母组成的前两个连续字符, 加() 就会将匹配到的结果提取出来, 然后通过 replace 将匹配到的结果替换为新的字符串, 形如: 结果 = 结果 + str
(4) 将手机号 12988886666 转化成 129 8888 6666
- function telFormat(tel){
- tel = String(tel);
- // 方式一
- return tel.replace(/(\d{3})(\d{4})(\d{4})/,function (rs,$1,$2,$3){
- return $1+""+$2+" "+$3
- });
- // 方式二
- return tel.replace(/(\d{3})(\d{4})(\d{4})/,"$1 $2 $3");
- }
(\d{3}\d{4}\d{4}) 可以匹配完整的手机号, 并分别提取前 3 位, 4-7 位和 8-11 位,"$1 $2 $3" 是在三个结果集中间加空格组成新的字符串, 然后替换完整的手机号.
(5)replace()方法全局替换变量
简单替换字符: string.replace("a","b"); (把 a 替换成 b)
全局替换字符: string.replace(/a/g,"b");(全局把 a 替换成 b)
但是如果是全局替换一个变量内容, 如下, 给一个电话号码中间加 * 号:
- var phone = "15512345678";
- var sliceNumber = phone.slice(3,phone.length - 3);
- var newPhone = phone.replace(new RegExp(sliceNumber,'g'),'****');
- console.log(newPhone); //155****678
常用实例
匹配第一个 bat 或者 cat, 不区分大小写: /[bc]at/i 或者 new RegExp("[bc]at","i");
匹配所有以 "at" 结尾的 3 个字符组合, 不区分大小写:/.at/gi;
只能输入数字:^[0-9]*$;
只能输入 n 位的数字:^\d{n}$
只能输入至少 n 位的数字:^\d{n,}$
只能输入 m~n 位的数字:^\d{m,n}$
只能输入零和非零开头的数字:^(0|[1-9][0-9]*)$
只能输入有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
只能输入有 1~3 位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
只能输入非零的正整数:^\+?[1-9][0-9]*$
只能输入长度为 3 的字符:^.{3}$
只能输入由 26 个英文字母组成的字符串:^[A-Za-z]+$
只能输入由数字和 26 个英文字母组成的字符串:^[A-Za-z0-9]+$
只能输入由数字, 26 个英文字母或者下划线组成的字符串:^\w+$
验证用户密码: 以字母开头, 长度在 6~18 之间, 只能包含字符, 数字和下划线:^[a-zA-Z]\w{5,17}$
验证是否含有 ^%&',;=?$" 等字符:[^%&',;=?$\x22]+
只能输入汉字:^[\u4e00-\u9fa5]{0,}$
验证 Email 地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
验证 InternetURL:^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
验证身份证号(15 位或 18 位数字):^\d{15}|\d{18}$
验证 IP 地址:^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$
匹配两个两个重叠出现的字符 例如,"aabbc11asd", 返回结果为 aa bb 11 三组 match:(\w)\1
- str="中文;;a"
- alert(str.match(/[\u0000-\u00ff]/g)) // 半角
- alert(str.match(/[\u4e00-\u9fa5]/g)) // 中文
- alert(str.match(/[\uff00-\uffff]/g)) // 全角
- var str = 'assssjdssskssalsssdkjsssdss';
- var arr = str.split(''); // 把字符串转换为数组
- str = arr.sort().join(''); // 首先进行排序, 这样结果会把相同的字符放在一起, 然后再转换为字符串
- //alert(str); // aaddjjkklsssssssssssssssss
- var value = '';
- var index = 0;
- var re = /(\w)\1+/g; // 匹配字符, 且重复这个字符, 重复次数至少一次.
- str.replace(re,function($0,$1){
- //alert($0); 代表每次匹配成功的结果 : aa dd jj kk l sssssssssssssssss
- //alert($1); 代表每次匹配成功的第一个子项, 也就是 \ w: a d j k l S
- if(index<$0.length){ // 如果 index 保存的值小于 $0 的长度就进行下面的操作
- index = $0.length; // 这样 index 一直保存的就在最大的长度
- value = $1; //value 保存的是出现最多的这个字符
- }
- });
- alert('最多的字符:'+value+', 重复的次数:'+index); // s 17
- //^ : 放在正则的最开始位置, 就代表起始的意思, 注意 /[^a] / 和 /^[a]/ 是不一样的, 前者是排除的意思, 后者是代表首位.
- //$ : 正则的最后位置 , 就代表结束的意思
- // 首先想 QQ 号的规则
- var aInput = document.getElementsByTagName('input');
- var re = /^[1-9]\d{4,11}$/;
- //123456abc 为了防止出现这样的情况, 所以必须限制最后
- // 首位是 0-9, 接着是 4-11 位的数字类型.
- aInput[1].onclick = function(){
- if( re.test(aInput[0].value) ){
- alert('是 QQ 号');
- }else{
- alert('不是 QQ 号');
- }
- };
- var str = 'hello';
- alert( '('+trim(str)+')' );// 为了看出区别所以加的括号. (hello)
- function trim(str){
- var re = /^\s+|\s+$/g; // | 代表或者 \s 代表空格 + 至少一个 前面有至少一个空格 或者后面有至少一个空格 且全局匹配
- return str.replace(re,''); // 把空格替换成空
- }
- Email:^\w+@[a-z0-9]+(\.[a-z]+){1,3}$
- // 起始至少为一个字符 (\w 字母, 数字或者下划线), 然后匹配 @, 接着为任意个字母或者数字,\. 代表真正的点,. 后面为至少一个的字符(a-z), 同时这个(比如. com) 整体为一个子项作为结束, 可以出现 1-3 次. 因为有的邮箱是这样的. cn.NET.(xxxx.@qq.com xxxx.@163.com xxxx.@16.cn.NET )
来源: https://www.cnblogs.com/moqiutao/p/6513628.html