1. 如何创建正则表达式?
RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。
直接量语法
/pattern/attributes
何时使用:使用固定的正则表达式时
创建 RegExp 对象的语法:
new RegExp(pattern, attributes);
何时使用:如果正则表达式需要动态拼接
强调:"正则表达式"中的\都要变为\\
参数
参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。
参数 attributes 是一个可选的字符串,包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持 m 属性。如果 pattern 是正则表达式,而不是字符串,则必须省略该参数。
方括号
方括号用于查找某个范围内的字符:
表达式 描述 [abc] 查找方括号之间的任何字符。 [^abc] 查找任何不在方括号之间的字符。 [0-9] 查找任何从 0 至 9 的数字。 [a-z] 查找任何从小写 a 到小写 z 的字符。 [A-Z] 查找任何从大写 A 到大写 Z 的字符。 [A-z] 查找任何从大写 A 到小写 z 的字符。 [adgk] 查找给定集合内的任何字符。 [^adgk] 查找给定集合外的任何字符。 (red|blue|green) 查找任何指定的选项。 元字符
元字符(Metacharacter)是拥有特殊含义的字符:
元字符 描述 . 查找单个字符,除了换行和行结束符。 \w 查找单词字符。 \W 查找非单词字符。 \d 查找数字。 \D 查找非数字字符。 \s 查找空白字符。 \S 查找非空白字符。 \b 匹配单词边界。 \B 匹配非单词边界。 \0 查找 NUL 字符。 \n 查找换行符。 \f 查找换页符。 \r 查找回车符。 \t 查找制表符。 \v 查找垂直制表符。 \xxx 查找以八进制数 xxx 规定的字符。 \xdd 查找以十六进制数 dd 规定的字符。 \uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。 量词
量词 描述 n+ 匹配任何包含至少一个 n 的字符串。 n* 匹配任何包含零个或多个 n 的字符串。 n? 匹配任何包含零个或一个 n 的字符串。 n{X} 匹配包含 X 个 n 的序列的字符串。 n{X,Y} 匹配包含 X 或 Y 个 n 的序列的字符串。 n{X,} 匹配包含至少 X 个 n 的序列的字符串。 n$ 匹配任何结尾为 n 的字符串。 ^n 匹配任何开头为 n 的字符串。 ?=n 匹配任何其后紧接指定字符串 n 的字符串。 ?!n 匹配任何其后没有紧接指定字符串 n 的字符串。 RegExp 对象属性
RegExp 对象方法
方法 描述 FF IE compile 编译正则表达式。 1 4 exec 检索字符串中指定的值。返回找到的值,并确定其位置。 1 4 test 检索字符串中指定的值。返回 true 或 false。 1 4 exec: 既获得每个关键字的内容,又获得每个关键字的位置: var arr=reg.exec(str) 特点:1. 每次只返回一个关键字的内容,存在arr的[0] 如果找不到了,返回null 2. 将本次找到的关键字的位置保存在arr.index 3. 自动调整reg.lastIndex属性为下次开始的位置var str="那天,我去了她家,我说:我草,你家真大。"+ "她要和我去草坪野餐。"+ "我草草收拾了餐桌。"+ "她说:我去去就来"; //我去 我草 我去草 我去去 我草草 var reg=/我[去草][去草]?/; var arr=null; while((arr=reg.exec(str))!=null){ //将str中所有敏感词替换为**或*** str=str.replace(reg,arr[0].length==2?"**":"***"); /*输出: "在位置 ? 发现敏感词 ?" console.log( "在位置 "+arr.index+" 发现敏感词:"+arr[0]);*/ } console.log(str);// 验证:var bool=reg.test(str); 如果str符合reg的要求,返回true,说明验证通过 否则返回false,说明验证未通过 ***强调:凡是验证,前加^后加$ 如果不加,只要局部匹配,就通过。匹配指定位置: ^匹配开始位置的xxx,比如: ^\s+匹配字符串开头的空字符 $匹配结束位置的xxx,比如:\s+$ 匹配字符串结尾的空字符 匹配开头或结尾的空字符:^\s+|\s+$ 前加^后加$,且中间没有|:^xxxx$必须和正则完全匹配 ***今后:做验证:都要前加^,后加$ \b:表示单词边界:比如:\bno\b,只找单词no
查找:2种: 1. 只判断是否包含关键字:不考虑具体内容和个数 var i=str.search(reg); 只能返回第一个找到的关键字的位置 找不到,返回-1 2. 获取所有关键字的内容:不考虑位置 var kwords=str.match(reg); 返回所有关键字的内容,保存在kwords数组中 ***找不到,返回null,都要先判断不为null,再使用;kwords.length,如果kwords为null,则报错!
替换或删除子字符串: var newStr=str.replace(reg,"替换字符"); 格式化字符串: 正则表达式中的每个(),都是一个子表达式 每个子表达式都会自动获得一个从1开始的编号 替换时,可用$n,指代本次匹配中第n个子表达式的对应内容
<span style="background-color: rgb(204, 255, 255);"><script></span>
<span style="background-color: rgb(204, 255, 255);"><span style="white-space:pre"> </span>/*去掉字符串开头或结尾的空字符*/ function ltrim(){//只去掉开头的空字符 //定义正则表达式只匹配开头的空字符,保存在reg中 //替换str中满足reg规则的子字符串为"", 并返回 return str.replace(/^\s+/,""); } function rtrim(){//只去掉结尾的空字符 //定义正则表达式只匹配结尾的空字符,保存在reg中 //替换str中满足reg规则的子字符串为"", 并返回 return str.replace(/\s+$/,""); } function trim(){//同时去掉开头或结尾的字符 //定义正则表达式匹配开头或结尾的空字符,保存在reg中 //替换str中满足reg规则的子字符串为"", 并返回 return str.replace(/^\s+|\s+$/g,""); } var str=" \t Hello World \t"; console.log(ltrim()); //"Hello World \t" console.log(rtrim()); //" \t Hello World" console.log(trim()); //"Hello World"</span>
<span style="background-color: rgb(204, 255, 255);"></script></span>
分隔字符串: var subs=str.split(reg[,count]);
var stmt="we two who and who";
var words=stmt.split(/\s+/);
console.log(words);
//遍历words中每个单词
for(var i=0;i<words.length;i++){
// 将当前位置的单词的首字母改为大写,再拼接上剩余字符,再保存回当前位置
words[i]=words[i][0].toUpperCase()
+words[i].slice(1);
}//(遍历结束)将words,按" "拼接为新句子,存回stmt中
stmt=words.join(" ");
console.log(stmt); //"We Two Who And Who"
var mail="zhangdong@tedu.cn";
var arr=mail.split(/@/);
console.log("用户名:"+arr[0]);
console.log("域名:"+arr[1]);
var msg="Tom@补给兵@60%#Mary@医护兵@80%#John@特种兵@30%"
function show(){
//按#切割msg,将结果保存在roles中
var roles=msg.split(/#/);
//遍历roles中每个角色字符串
for(var i=0;i<roles.length;i++){
// 再按@切割当前角色字符串,结果保存在arr中
var arr=roles[i].split(/@/);
// 输出:"名 兵种 生命:值"
console.log(
arr[0]+" "+arr[1]+" 生命:"+arr[2]);
}
}
show();
/*
Tom 补给兵 生命:60%
Mary 医护兵 生命:80%
John 特种兵 生命:30%
*/
RegExp.$n: 获得本次匹配中第n个子表达式匹配的内容
var birth="19831226";
var reg=/(\d{4})(\d{2})(\d{2})/;
// 1 2 3
birth=birth.replace(reg,"$1年$2月$3日");
console.log(birth);
var date="20151207一下050632";
//定义正则reg
var reg=/(\d{4})(\d{2})(\d{2})([\u4e00-\u9fa5])([\u4e00-\u9fa5])(\d{2})(\d{2})(\d{2})/;
//用reg格式化date,再保存回date中
date=date.replace(reg,"$1年$2月$3日 星期$4 $5午 $6:$7:$8");
console.log(date);
//"2015年12月07日 星期一 下午 05:06:32"
贪婪模式:
在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"{m,n}", "{m,}", "?", "*", "+",具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 "dxxxdxxxd",举例如下:
贪婪模式:
表达式 | 匹配结果 |
---|---|
(d)(\w+) | "\w+" 将匹配第一个 "d" 之后的所有字符 "xxxdxxxd" |
(d)(\w+)(d) | "\w+" 将匹配第一个 "d" 和最后一个 "d" 之间的所有字符 "xxxdxxx"。虽然 "\w+" 也能够匹配上最后一个 "d",但是为了使整个表达式匹配成功, "\w+" 可以 "让出" 它本来能够匹配的最后一个 "d" |
由此可见,"\w+" 在匹配的时候,总是尽可能多的匹配符合它规则的字符。 虽然第二个举例中,它没有匹配最后一个 "d",但那也是为了让整个表达式能够匹配成功。 同理,带 "*" 和 "{m,n}" 的表达式都是尽可能地多匹配,带 "?" 的表达式在可匹配可不匹配的时候, 也是尽可能的 "要匹配"。这 种匹配原则就叫作 "贪婪" 模式 。
非贪婪模式: 在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。这种匹配原则叫作 "非贪婪" 模式,也叫作 "勉强" 模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。举例如下,针对文本 "dxxxdxxxd" 举例:
表达式 | 匹配结果 |
---|---|
(d)(\w+?) | "\w+?" 将尽可能少的匹配第一个 "d" 之后的字符,结果是:"\w+?" 只匹配了一个 "x" |
(d)(\w+?)(d) | 为了让整个表达式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以让后边的 "d" 匹配,从而使整个表达式匹配成功。因此,结果是:"\w+?" 匹配 "xxx" |
更多的情况,举例如下: 举例1:表达式 "<td>(.*)</td>" 与字符串 "<td><p>aa</p></td> <td><p>bb</p></td>" 匹配时,匹配的结果是:成功;匹配到的内容是 "<td><p>aa</p></td> <td><p>bb</p></td>" 整个字符串, 表达式中的 "</td>" 将与字符串中最后一个 "</td>" 匹配。 举例2:相比之下,表达式 "<td>(.*?)</td>" 匹配举例1中同样的字符串时,将只得到 "<td><p>aa</p></td>", 再次匹配下一个时,可以得到第二个 "<td><p>bb</p></td>"。