1. 正则表达式- 1.1 创建
- 1.2 RegExp 对象属性
- 1.3 RegExp 对象方法
- 1.4 RegExp 分组
2. 元字符和正则表达式规则
正则表达式本身就是一种语言,由普通字符和特殊的元字符(metacharacters)组成。它描述了字符串的匹配模式,用于转换和处理字符串。
其中,元字符(metacharacters)也是由普通字符组成,具有特殊意义。比如 {3}
代表了将前面的字符或分组重复匹配三次,$
代表了匹配一行的结束位置。(更多的元字符请看下面的 表格。)
正则表达式常被用来执行复杂的 “搜索-替换” 、验证字符串格式是否正确。
当今的大多数程序设计语言都包含正则表达式。甚至包括脚本语言、编辑器、应用程序、数据库和一些命令行的工具也包含正则表达式工具。下面介绍 Javascript 中实现正则表达式的 Regex
对象。
Regex
是 Javascript 的内置对象,描述一个字符串的匹配模式,为字符串操作提供了强大的匹配和替换方法。
和数组、对象差不多,Regex
对象的创建也有常量、构造函数、普通函数三种创建方式:
直接量语法
构造函数
new RegExp( pattern , attributes ) ;
普通函数
RegExp( pattern , attributes ) ;
其中的 pattern
是正则表达式的匹配模式,由字符和元字符(表格)构成,attributes
是正则表达式的标记,可以是 "i"
、"g"
、"m"
三个字母或三个字符的任意组合:
"i"
:大小写不敏感"g"
:全局匹配(查找所有匹配而非在找到第一个匹配后停止)"m"
:多行匹配
在使用函数创建正则表达式的时候,如果 pattern 不是一个字符串,而是一个正则表达式,则忽略第二个参数:
var a = /ch/ig ;
var b = new RegExp( /ch/ig) ;
var c = RegExp( "ch" , "ig" ) ;
regexOjbect.source
属性是一个只读的字符串,包含了描述这个正则表达式的文本;regexOjbect.global
属性是一个只读的布尔值,表明这个正则表达式是否为具有标识 "g"
;regexOjbect.ignoreCase
属性是一个只读的布尔值,表明这个正则表达式是否为具有标识 "i"
;regexOjbect.multiline
属性是一个只读的布尔值,表明这个正则表达式是否为具有标识 "m"
;regexOjbect.lastIndex
属性是一个数值,如果正则表达式有 “g” 标识,这个属性表明下一次检索的起始位置。
var reg = /ch/g ;
var testString = "String type contains one char or a set of chars."
alert( reg.source ) ;alert( reg.global ) ;alert( reg.ignoreCase) ;alert( reg.multiline) ;alert( reg.lastIndex) ;reg.test( testString ) ;alert( reg.lastIndex) ;reg.test( testString ) ;alert( reg.lastIndex) ;reg.test( testString ) ;alert( reg.lastIndex) ;
可以看到,当正则表达式匹配结束或失败时,regexOjbect.lastIndex
被重置。
test
Regex.test
方法测试正则表达式指定的模式是否出现在字符串中,返回 true
或 false
。
var a = /ch/ig ;
a.test( "chinses " ) ;a.test( "abc") ;
compile
Regex.compile
方法可以在脚本执行过程中编译正则表达式,也可以改变和重新编译正则表达式。形式如下:
RegExpObject.compile( regexp , attributes ) ;
regexp
是一个正则表达式,用于替换 RegExpObject
。
modifier
是正则表达式的匹配属性( "i"
/ "g"
/ "i"
)。
如果缺省参数,RegExpObject
被重置为一个空的正则表达式 //
。
var reg = /man/ ;
"I'm woman !".replace( reg , "child" ) ;reg.compile( /(wo)?man/ ) ;
"I'm woman !".replace( reg , "child" ) ;
如果 regexp
是正则表达式本身,结果就是重新编译并重置它的属性,比如 lastIndex
。
exec
Regex.exec
方法用于检索字符串中正则表达式的匹配。形式如下:
var ResultArray = RegExpObject.exec( string ) ;
Regex.exec
方法返回一个数组:
- 数组的元素,就是匹配的结果;
- 数组的属性
index
表示匹配发生的位置,input
表示原始字符串; - 未找到匹配返回
null
,而不是空数组 [ ]
;
执行 exec
后:
- 如果匹配成功,正则表达式的属性
lastIndex
设为匹配文本后面的位置; - 如果匹配失败,正则表达式的属性
lastIndex
设为 0 。
非全局匹配的情况下,exec
的返回结果和 String.match
相同。
[ 匹配的结果 , 第 1 个子表达式匹配的结果 , 第二个..... , 第 n 个子表达式匹配的结果 ]
全局匹配的情况下,可以通过反复调用 exec
方法来遍历字符串中的所有匹配文本。
var str = "30-AC-F6-B1-EC-14" ;
var reg = /(\d{2})|([A-Z]{2})/g ;
reg.exec( str ) ;alert( reg.lastIndex ) ;reg.exec( str ) ;alert( reg.lastIndex ) ;
用 for
来遍历:
var str = "30-AC-F6-B1-EC-14" ;
var reg = /(\d{2})|([A-Z]{2})/g ;
var match = reg .exec( str ) ;
var numberArr = [ ] ;
var literalArr = [ ] ;
while( match ){if( match[ 1 ] )numberArr.push( match[ 1 ] );if( match[ 2 ] )literalArr.push( match[ 2 ] ); match = reg .exec( str ) ;
}
alert("数字:"+ numberArr + " 字母:" + literalArr );
正则表达式中,使用括号 ( )
进行分组。
分组的正则表达式有两个作用:一是可以让重复的模式作用于整个组而不是单一字符,另一个是可以用特殊转义序列对其进行引用。
var reg = /^(.).*\1$/ ;reg.test( "seats" ) ;
其中使用 \n
引用前面第 n
个 捕获子表达式 的捕获结果。
分组的捕获结果,还可以用 RegExp 的静态属性 $1...$9
引用。在 string.replace
方法中:
var reg = /(\d+)/g ;"var a = 98 + 23 ;".replace( reg , "<i>$1</i>") ;
在 string.replace
的 replacement
参数中 "$1" ... "$9"
拥有特殊意义,引用模式匹配过程中 捕获子表达式 捕获的结果。
也可以在 replacement
外使用 RegExp.$1 ... RegExp.$9
访问对应分组捕获的结果。
var reg = /(\d+)/g ;"var a = 98 + 23 ;".replace( reg , "<i>" + RegExp.$1 + "</i>") ;
var reg = /(\d+)-(\d+)/g ;
reg.exec( "021-88776655,010-99585960" ) ;alert( "区号:" + RegExp.$1 + " 号码:" + RegExp.$2 ) ;reg.exec( "021-88776655,010-99585960" ) ;alert( "区号:" + RegExp.$1 + " 号码:" + RegExp.$2 ) ;
Character | Description |
---|
\ | \ 标志着下一个字符是一个特殊的字符。元字符拥有特殊的意义,如果想使用这些字符,需用 \ 转义: var reg1 = /\{/ ;var reg2 = /\(/ ;var reg3 = /\[/ ;var reg4 = /\\/ ;var reg5 = /\n/ ;
|
^ | ^ 匹配字符串的开始位置。如果进行多行(Multiline)匹配,^ 也会匹配 \n 、\r 后面的位置。 var reg = /^a/ ;
reg.test( "ab" ) ;reg.test( "ba" ) ;reg = "abc\ndef\rghi" ;
reg.replace( /^/gm , "-" ) ;
|
$ | $ 匹配字符串的结束位置。如果进行多行(Multiline)匹配,$ 也会匹配 \n 、\r 前面的位置。 var reg = /a$/ ;
reg.test( "ab" ) ;reg.test( "ba" ) ;reg = "abc\ndef\rghi" ;
reg.replace( /$/gm , "-" ) ;
|
* | * 匹配前面的字符或者分组 0 次或多次。如 zo* 匹配 “zo” 和 “zoo”,甚至是 “z”。 + 等价于 {1,} var reg = /zo*/ ;reg.test( "zoo" ) ;reg.test( "zo" ) ;reg.test( "z" ) ;reg.test( "loo" ) ;
|
+ | + 匹配前面的字符或者分组 1 次或多次。如 zo+ 匹配 “zo” 和 “zoo”,但不匹配 “z”。 + 等价于 {1,} var reg = /zo+/ ;reg.test( "zoo" ) ;reg.test( "zo" ) ;reg.test( "z" ) ;reg.test( "loo" ) ;
|
? | ? 匹配前面的字符或者分组 1 次或多次。如 do(es)? 匹配 “do” 和 “does” 。 ? 等价于 {0,1} var reg = /do(es)?/ ;reg.test( "do" ) ;reg.test( "does" ) ;reg.test( "to" ) ;
|
{n} | {n} 匹配前面的字符或者分组 n 次。其中 n 是非负整数。如 o{2} 匹配 "food" 的 2 个 "o" ,不匹配 "do" 中的 1 个 "o" 。 var reg = /o{2}/ ;
reg.test( "too" ) ;reg.test( "food" ) ;reg.test( "to do" ) ;
|
{n,} | {n,} 匹配前面的字符或者分组至少 n 次。其中 n 是非负整数。如 o{1} 匹配 "yahoo" 的 2 个 "o" ,也匹配 "yahooooooooo" 中的所有 "o" 。 {1,} 等价于 + 。 var reg = /o{2}/ ;
reg.test( "google" ) ;reg.test( "yahooooo" ) ;reg.test( "to do" ) ;
|
{n,m} | {n,m} 匹配前面的字符或者分组至少 n 次、至多 m 次。其中 n 和 m 都是非负整数。如 o{1,3} 匹配 "yahoo" 的前 3 个 "o" ,也匹配 "yahooooooooo" 中的前 3 个 "o" 。 {0,1} 等价于 ? 。 注意:数字和逗号之间不能有空格。 var reg = /o{2}/ ;
reg.test( "google" ) ;reg.test( "yahooooo" ) ;reg.test( "to do" ) ;
|
? | 其实 ? 有两个用途。 第一个用途上面提到了,用来匹配前面字符或分组 0 次或 1 次。 第二个用途,用在其他量词(比如 * , + , ? , {n} , {n,} , {n,m} )的后面,指示匹配模式为 “非贪婪匹配”,与之相反,默认匹配规则是 “贪婪匹配”,即尽量匹配更多的字符。比如,o+ 匹配 “ooooo” 中的全部 “o”,而 o+? 匹配第一个 “o”。 var reg = /o+?/ ;
reg.test( "google" ) ;reg.test( "yahooooo" ) ;reg.test( "to do" ) ;
|
. | . 匹配除了 "\n" 外的任何字符。 想要匹配 "\n" 可以使用 [\s\S] 。 var reg = /^a.*a$/ ;reg.test( "abcdefga" ) ;reg.test( "abc") ;
|
(pattern) | (pattern) 匹配模式 pattern 并捕获结果。 RegExp.exec 返回的数组中: - 第一个元素是整个正则表达式匹配到的字符串;
- 后面的元素,依次是针对该次匹配的子表达式
pattern 匹配结果。 - 想要子表达式捕获结果,需要用
( ) 包围起来。
var reg = /ch/ ;reg.exec( "chese" ) ;reg = /(c)(h)/ ;
reg.exec( "chese" ) ;reg = /(ch)/ ;
reg.exec( "chese" ) ;reg = /(ch)|(ese)|(en)/ ;
reg.exec( "chese" ) ;
|
(?:pattern) | (?:pattern) 匹配模式 pattern 并但不捕获结果。 加 ( ) 有时并不是为了捕获,而仅仅为了 “分组”,这时可以用这个元字符。 var reg = /^.*(?:\.|。)$/ ; 匹配以句号结尾的字符串
reg.exec( "Hello !" ) ;reg.exec( "To be continued ." ) ;
|
(?=pattern) | (?=pattern) 零宽正向预测先行断言。断言此位置的后面匹配 pattern ,不捕获结果(零宽)。 先行断言 (?=pattern) 不会消耗字符,也就是说,下一次匹配是从上一次匹配之后的位置开始的,而不是在pattern 之后。 var reg = /Windows (?=2008|7)/g ; var str = "最低配置 Windows 2008 ,推荐 Windows 7 。" ;
alert( reg.exec( str ) ) ;alert( reg.lastIndex ) ;alert( reg.exec( str ) ) ;alert( reg.lastIndex ) ;
|
(?!pattern) | (?!pattern) 零宽负向预测先行断言,断言此位置的后面不匹配 pattern ,不捕获结果(零宽)。 先行断言 (?!pattern) 不会消耗字符,同上。 var reg = /Windows (?!2000|xp)/g ;var str = "最低配置 Windows 2008 ,推荐 Windows 7 。" ;
alert( reg.exec( str ) ) ;alert( reg.lastIndex ) ;alert( reg.exec( str ) ) ;alert( reg.lastIndex ) ;
|
x|y | x|y 匹配 x 或 匹配 y 。 比如 see|saw 匹配 "see" ,也可以匹配 "saw" var reg = /hello|hi/i ;reg.test( "Hello" ) ;reg.test( "Hi, are you ok !") ;
|
[xyz] | [xyz] 代表一个字符集(字符集中的元字符不需要转义)。匹配任何出现在中括号 [ ] 中的字母 。 比如 [abc] 匹配 "plain" 中的 “a”。 可以使用 - 表示字符的范围: - 英文字母:
[a-zA-Z] ; - 阿拉伯数字:
[0-9] ; - 罗马数字:
[Ⅰ-Ⅻ] ; - 希腊字母、拼音字母…… ;
- Unicode 字符编码:[udddd-udddd],其中
d 代表一个 16 进制的数字; - Latin-1 字符编码:[xdd-xdd],其中
d 代表一个 16 进制的数字;
var reg = /[a-zA-Z-_]+/g ;"I wanna be a scientist .".match( reg ) ;
|
[^xyz] | [^xyz] 代表一个排除字符集,不匹配任何出现在中括号 [ ] 中的字母 。 比如 [^abc] 匹配 "see" 中的 “s”。 var reg = /[<][^>].*?[>]/g ;"<div></div>".match( reg ) ;
|
\b | \b 匹配单词边界。 比如 er\b 匹配 "her" 中的 “er”,但不匹配 “verb” 中的 “er” 。 \b 通常用于查找位于单词的开头或结尾的匹配。 var reg = /\b[a-zA-Z-_]+(es|s)\b/g ;"I bought 1 cup, 5 apples, and 6 dozens of eggs".match( reg ) ;
|
\B | \B 匹配非单词边界的位置。 - 匹配位置的上一个和下一个字符的类型是相同的:即必须同时是单词字符,或必须同时是非单词字符;
- 字符串的开头和结尾处被视为非单词字符。
比如 er\B 不匹配 "her" 中的 “er”,匹配 “verb” 中的 “er” 。 \B 通常用于排除位于单词的开头或结尾的匹配。 var reg = /[a-z-_]*\Boo\B[a-z-_]*/ig ;"I like reading book in the room too !".match( reg ) ;
|
\cx | \cx 匹配由 x 字符表示的控制字符。 如 \cM 表示 Ctl+M 或回车字符 "\r" ,\cJ 表示换行符 "\n" 。 /td>
|
\d | \d 匹配一个数字,相当于 [0-9] 。 var reg = /\d\d/g ;"[55,25,2422,579]".match( reg ) ;
|
\D | \D 匹配一个非数字的字符,相当于 [^0-9] 。 |
\f | \f 匹配一个换页符,相当于 \x0c 或 \cL 。 |
\n | \n 匹配一个换行符,相当于 \x0a 或 \cJ 。 |
\r | \r 匹配一个回车符,相当于 \x0d 或 \cM 。 |
\s | \s 匹配空白字符,包括空格 " " 、制表符 "\t" 、翻页符 "\f" 、换行符 "\n" 、垂直制表符 "\t" 。 相当于 [\f\n\r\t\v] |
\S | \S 匹配非空白字符,相当于 [\f\n\r\t\v] |
\t | \t 匹配制表符,相当于 \x09 、\cI 。 |
\v | \v 匹配垂直制表符,相当于 \x0b 、\cK 。 |
\w | \w 匹配任何单词字符,包括下划线,相当于 [A-Za-z0-9_] 。 |
\W | \w 匹配任何非单词字符,相当于 [^A-Za-z0-9_] 。 |
\xn | \xn 匹配 Latin-1 字符,其中的 n 为 16 位的数字。 。 所有的 ASCII 字符都可以用 \xn 来表示,如 \x41 匹配 “A” 。 |
\num | \num 引用前面第 num 个 捕获子表达式 捕获到的字符串。 num 是一个正整数。 如 (.)\1 同一个字符匹配两次。 var reg = /(.)\2/g ;
"book、see".match( reg ) ;
|
\n | \n n 代表一个数字。 - 如果
\n 前面有至少 n 个 捕获子表达式 ,那么它就作为 “后向引用”,等同于上面的 \num 。 - 如果不满足上面的条件,n 又是一个八进制(0-7),那么它作为八进制转义码。
|
\nm | \nm n 、 m 代表一个数字。 - 如果
\nm 前面是一个捕获字表达式: - 如果
\nm 至少有 nm 个捕获字表达式,则将 \nm 视作后向引用; - 如果
\nm 至少有 n 个捕获字表达式,则将 \n 视作后向引用,m 作为一个普通数字;
- 如果不满足上面的条件,
n 、m 又是八进制(0-7),那么 \nm 作为八进制转义码。
|
\nml | \nmlnm 当 n 在 0 - 3 间,m 、l 在 0 - 7 间, 匹配八进制转义码 nml 。 |
\un | \un 匹配编码为 n 的 Unicode 字符 。 |
相关文章
- Javascript – 字符串
- Javascript – 集合
- JavaScript Scope Chains and Closures
- Javascript – 对象
- Javascript – 控制语句
- Javascript – 表达式和运算符
- Javascript – Explaining JavaScript scope and closures
- Javascript – 常量和变量