javascript 正则表达式
正则表达式(regular expression)是被用来匹配字符串中的字符组合的模式。
我个人对正则表达式的理解是,用特定的符号集(字符组合的模式)表示一般使用单一或多种字符集。
创建一个正则表达式
使用正则表达式直接量定义,例如:
1 var pattern = /s/;
使用RegExp
对象的构造函数,例如:
1 var pattern = new RegExp("s");
注意:正则表达式的模式会发生改变,或当你不确定要匹配的模式时(如用户输入),此时,比较适合用构造函数的方式。
编写一个正则表达式的模式
直接量字符
简单介绍一下test()用法,正则表达式.test(字符串),如果在字符串中查到匹配的字符串,则返回true.如/a/.test(
"a"
); //ture
字符 |
匹配 | 样例 | 备注 |
字母和数字字符 |
其自身 |
alert(/a/.test("a"));//true |
|
\0 |
NULL字符(\u0000) |
alert(/\0/.test("\0"));//true |
|
\t |
制表符(\u0009) |
alert(/\t/.test(" ")); //true |
引号内为制表符Tab |
\n |
换行符(\u000A) |
alert(/\n/.test("\n")); //true |
|
\v |
垂直制表符(\u000B) | alert(/\v/.test("\v")); //true | |
\f |
换页符(\u000C) | alert(/\f/.test("\f")); //true | |
\r |
换页符(\u000D) | alert(/\r/.test("\r")); //true |
直接量字符匹配的就是其自身。
有些非字母字符在字符串中表达时需要借用"\",如"\n"表示回车。
某些符号在正则表达式中有特殊含义,想要匹配,需加前缀"\"进行转义。如
1 alert(/\\/.test("\\")); //true
字符类
将直接量字符放在一个方括号内就组成了字符类(character class)。
字符 | 匹配 |
样例 |
解释 |
[...] | 方括号内任意字符 |
alert(/[abc]/.test("a"));//true alert(/[abc]/.test("b"));//true alert(/[abc]/.test("c"));//true |
简单字符 最简单字符类,如/[abc]/ 作用是将方括号内的字符看作一个字符,与其中之一匹即可。 |
[x-x] | 方括号内连续的字符 |
alert(/[a-c]/.test("a"));//true alert(/[a-c]/.test("b"));//true alert(/[a-c]/.test("c"));//true |
连续 利用"-"简写顺序连接的字符。如/[a-c]/ |
[^...] | 排除方括号内任意字符 |
alert(/[^abc]/.test("a"));//false alert(/[^abc]/.test("b"));//false alert(/[^abc]/.test("c"));//false alert(/[^abc]/.test("d"));//true |
反向 对简单字符类取反。如/[^abc]/ 匹配排除所列出的字符以外的字符。 |
[..1..2..3] | 匹配组合条件的字符 |
alert(/[a-cA-C2]/.test("b"));//true alert(/[a-cA-C2]/.test("B"));//true alert(/[a-cA-C2]/.test("2"));//true alert(/[^a-cA-C2]/.test("2"));//false |
组合 |
. | 除换行符\n和其他Unicode行终止符\r之外的任意字符 |
alert(/./.test("\r"));//false alert(/./.test("\n"));//false alert(/./.test("a"));//true |
等价于 [^\n\r]
|
\w | ASCII字符,即大小写字符和数字 |
alert(/\w/.test("a"));//true alert(/\w/.test("正"));//false |
等价于[a-zA-Z0-9] |
\W | 除ASCII字符,即除大小写字符和数字 |
alert(/\w/.test("a"));//false alert(/\w/.test("正"));//true |
等价于[^a-zA-Z0-9] |
\s | Unicode空白字符 |
alert(/\s/.test("\t"));//true alert(/\s/.test("\n"));//true |
等价于[ \t\n\x0B\f\r] |
\S | 除Unicode空白字符 |
alert(/\s/.test("\t"));//false alert(/\s/.test("\n"));//false |
等价于[^ \t\n\x0B\f\r] |
\d | ASCII数字 |
alert(/\d/.test("1"));//true |
等价于[^0-9] |
\D | 除ASCII数字 |
alert(/\d/.test("1"));//false |
等价于[0-9] |
[\b] | 退格直接量(特例) |
alert(/[\b]/.test("\b"));true |
当需要匹配一个退格直接量时,不可以/\b/,需用[\b]表示 |
重复
简单介绍一下exec()方法,它和test()用法差不多,只是返回的是匹配到的内容。
当需要匹配一个6位数字时,正则为/\d\d\d\d\d\d\/,为方便简写,有等价写法/\d{6}/
字符 | 含义 | 样例 | 备注 |
{n,m} | 匹配前一项至少n次,但不能超过m次 |
alert(/\d{2,3}/.exec("1"));//null alert(/\d{2,3}/.exec("12"));//12 alert(/\d{2,3}/.exec("1234"));//123 |
默认情况下是贪婪重复,也就是更多的匹配,第三个样例匹配123,并非12 这在后面会详细分析 |
{n,} | 匹配前一项至少n次 |
alert(/\d{2,}/.exec("1"));//null alert(/\d{2,}/.exec("12"));//12 alert(/\d{2,}/.exec("1234"));//1234 |
|
{n} | 匹配前一项n次 |
alert(/\d{6}/.exec("12345"));//null alert(/\d{6}/.exec("1234567"));//123456 |
|
? | 匹配一项0次或1次,等价于{0,1} |
alert(/\d?a/.exec("1a"));//1a alert(/\d?a/.exec("a"));//a |
|
+ | 匹配前一项1次或多次,等价于{1,} |
alert(/\d+a/.exec("a"));//null alert(/\d+a/.exec("1234567a"));//1234567a |
|
* | 匹配前一项0次或多次,等价于{0,} |
alert(/\d+a/.exec("a"));//a alert(/\d+a/.exec("1234567a"));//1234567a |
非贪婪重复
默认情况下,之前所碰到的重复都是贪婪重复。如
alert(/\d{2,3}/.exec("1234"));//123
在重复时,尽可能多的匹配元素,返回结果是123而非12。当我们希望匹配尽可能少的元素时就需要用到非贪婪重复。
要使用非贪婪模式,在重复条件后面加一个"?"即可。
1 alert(/\d{2,3}/.exec("1234"));//12 2 alert(/a\d??/.exec("a1234"));//a 3 alert(/a\d+?/.exec("a1234"));//a1 4 alert(/a\d*?/.exec("a1234"));//a
选择、分组和引用
正则表达式语法还包括指定选择项、子表达式分组和引用前一子表达式的特殊字符。
字符 | 含义 | 样例 | 备注 |
| | 选择,匹配符号左边或右边的子表达式 |
alert(/ab|cd|ef/.exec("ab"));//ab alert(/ab|cd|ef/.exec("ef"));//ef alert(/ab|bcd|ef/.exec("abcdef"));//ab |
注意,选择的顺序为从左到右. 发现匹配后,将忽略右边的匹配项 |
(。。。) |
子表达式,将几个项组合为一个单元,可以对这个单元进行重复*,+,{,},?。 选择|。并记住与之匹配的字符串 |
alert(/a(b)?/.test("a"));//true alert(/a|(bd)/.test("a"));//true alert(/a|(bd)/.test("bd"));//true |
|
(?:。。。) | 子表达式,与(。。。)就一个不同点,是不记忆匹配的字符串 |
alert(/a(?:b)?/.test("a"));//true |
|
\n |
引用,匹配和第N个分组第一次匹配的字符,而不是其正则表达,n为组索引,是从左到右的括号数, (?:...)跳过 |
alert(/(b|c)\1/.test("bb"));//true alert(/(a)(b|c)\2/.test("abb"));//true alert(/(a)(b|c)\2/.test("abc"));//false alert(/(?:a)(b|c)\1/.test("abb"));//true |
指定匹配位置
在匹配中,还有一些正则表达式的元素匹配的是字符位置,而不是实际的字符。
字符 | 含义 | 样例 | 备注 |
^ | 匹配字符串的开头 |
alert(/^b/.test("ab"));//false alert(/^b/.test("ba"));//true |
|
$ | 匹配字符串的在结尾 |
alert(/b$/.test("ab"));//true alert(/b$/.test("ba"));//false |
|
\b | 匹配一个单词的边界位置 |
alert(/\bjava\b/.test(" java "));//true alert(/\bjava\b/.test("java"));//true alert(/\bjava\b/.test("\njava\n"));//true alert(/\bjava\b/.test("isjavascript"));//false |
\b表示非单词边界,是位于字符\w和\W之间的位置, 或者\w和字符串的开头或\w和字符串的结尾 这种匹配可以匹配英文单词在任何位置的独立英文单词, 无论是在开头结尾或者是在空格回车中 注意,[\b]匹配的是退格符 |
\B | 匹配一个非单词边界位置 |
alert(/\bjava\b/.test("isjavascript"));//true |
|
(?=p) | 零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符 |
alert(/java(?=\:)/.test("java"));//false alert(/java(?=\:)/.test("java:"));//true//但匹配的结果是java |
匹配某个元素的位置,类似^,$,实际上就匹配元素的位置 |
(?!p) | 零宽负向先行断言,要求接下来的字符不与p匹配, |
alert(/java(?!\:)/.test("java "));//true alert(/java(?!\:)/.test("java:"));//false |
修饰符
修饰符是用以高级匹配模式的规则。
字符 | 含义 | 样例 | 备注 |
i | 执行不区分大小写的匹配 | alert(/a/i.test("A"));//true | |
g | 全局匹配,找到所有的匹配项 | 下一节详细解释 | |
m | 多行匹配模式,^和$对应会匹配每一行的开头和结尾 |
alert(/java$/m.test("java"));//true alert(/java$/m.test("my\njava"));//true alert(/java$/m.test("my\njava\n"));//true |
与String对象相关的正则方法
String支持4种正则表达式方法,分别为search(),replace(),match(),split()。
1.seach(),参数为一个正则表达式,返回匹配字符串的位置,如果查找失败,则返回-1。
1 alert("JavaScript".search(/script/i));//4
注意,seach()不支持全局搜索,它会忽略正则表达式参数中g。
1 alert("JavaScript".search(/a/g));//1
2.replace(),第一个参数为正则表达模式,第二个为匹配内容将替换的字符串,返回的是替换后的字符串。
1 var text = "javaScript,javascript"; 2 alert(text.replace(/javascript/gi, "JavaScript"));//JavaScript,JavaScript
回忆先前的引用知识点,\n引用的是第N个括号里匹配的内容,而在这里可以用$n在替换的字符串中引用。
1 var str = "John Smith"; 2 alert(str.replace(/(\w+)\s(\w+)/, "$2 $1"));//Smith John
当replce的参数为一个函数时,匹配的内容替换为函数的返回值。
典型的replacement函数:function(str,p1,p2,offset,s){}
参数说明:
str:匹配的字符串(类似$&)
p1,p2,...:只有在正则表达式内包含记忆括号时有效。(类似$n)
offset:字符串的位置
s:源字符串
1 console.log( 2 "both".replace(/(a|t)h/g,function(a,b,c,d){ 3 console.log(a);//th 4 console.log(b);//t 5 console.log(c);//2 6 console.log(d);//both 7 return "ss" 8 }) 9 )//boss
3.match(),参数为正则表达模式,
在执行全局检索时,返回一个字符串数组,内容是其匹配的内容。
1 alert("1 plus 2 equals 3".match(/\d+/g/)) //1,2,3
在执行非全局检索时,也返回一个数组a,假设数组的a[0]字符串是完整的匹配,而a[1]内容等同于$1,依次类推。
1 var str = "John Smith"; 2 alert(str.match(/(\w+)\s(\w+)/));//John Smith,John,Smith
4.split,使用字符串分隔符或者正则表达式分隔符拆分字符串,返回的是一个子字符串组成的数组
1 alert("123,456,789".split(","));//123,456,789 2 alert("1, 2, 3, 4, 5".split(/\s*,\s*/));//1,2,3,4,5
RegExp对象
正则表达式对象RegExp,除构造函数RegExp(),还包括其它属性和方法
RegExp属性
1.source,只读字符串,正则表达式的文本
2.ignoreCase,布尔,是否有i
3.global,布尔,是否有g
4.multiline,布尔,是否有m
5.lastIndex,在全局检索时,存储整个字符串下次检索开始的位置
RegExp方法
之前介绍过,并一直在使用,比较少用的信息暂不介绍了。
补充
1./[\u4e00-\u9fa5]/用于匹配单个汉字。
————————————————————————————————————————————————————————
练习题
1.匹配中文字符的开始码和结束码?
2.alert(/^[1-9]\d*$/.test("129d");
3.alert(/^[1-9]\d*$/.test("5");
4.alert(/^[A-Za-z0-9]+$/.test("hot123"));
5.alert(/^[A-Za-z0-9]+$/.test("mi ni"));
6.alert(/^[\u4e00-\u9fa5]+$/.test("你好"));
7.alert(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test("1@n"));
8.alert(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test("1+a@.com"));
9.^\s*<(\w+|!)[^>]*>
10.^<(\w+)\s*\/?>(?:<\/\1>|)$
11.
参考:
javascript权威指南
http://www.cnblogs.com/1000/archive/2011/09/04/2166618.html
等……