1. 如何创建正则表达式?RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。
直接量语法
/pattern/attributes
何时使用:使用固定的正则表达式时
创建 RegExp 对象的语法:
new RegExp(pattern, attributes);
何时使用:如果正则表达式需要动态拼接
强调:"正则表达式"中的\都要变为\\
参数
参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。
参数 attributes 是一个可选的字符串,包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持 m 属性。如果 pattern 是正则表达式,而不是字符串,则必须省略该参数。
修饰符
修饰符 | 描述 |
---|
i | 执行对大小写不敏感的匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
m | 执行多行匹配。 |
方括号
方括号用于查找某个范围内的字符:
表达式 | 描述 |
---|
[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
支持正则表达式的 String 对象的方法
方法 | 描述 | FF | IE |
---|
search | 检索与正则表达式相匹配的值。 | 1 | 4 |
match | 找到一个或多个正则表达式的匹配。 | 1 | 4 |
replace | 替换与正则表达式匹配的子串。 | 1 | 4 |
split | 把字符串分割为字符串数组。 |
查找:2种:1. 只判断是否包含关键字:不考虑具体内容和个数var i=str.search(reg);只能返回第一个找到的关键字的位置找不到,返回-12. 获取所有关键字的内容:不考虑位置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>[/code]
<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 3birth=birth.replace(reg,"$1年$2月$3日");console.log(birth);var date="20151207一下050632";//定义正则regvar 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>"。