接触和使用正则表达式也有一段时间了,一直没有总结过,导致长时间不用的时候,又难免生疏,现在总结下,有时间就可拿来翻翻。
Javascript的RegExp类表示正则表达式类,String和RegExp都定义了正则表达式的有关方法,而后者可以进行强大的模式匹配和文本检索与替换功能,javascript中的正则表达式是perl5的正则表达式的大型子集。
js中正则表达式的定义
var pattern = /s$/;
var pattern = new RegExp("s$","g");
两种方式都会生成一个RegExp对象,这个正则表达式用于匹配以s为结尾的字符串。
javascript也支持非字母的字符匹配,这些字符需要通过反斜线(\)作为前缀进行转义,比如转义字符\n用以表示匹配换行符。
\o | NUL字符(\u0000) |
\t | 制表符(\u0009) |
\n | 换行符(\u000A) |
\v | 垂直制表符(\u000B) |
\f | 换页符(\u000C) |
\r | 回车符(\u000D) |
\xnn | 由十六进制nn指定的拉丁字符,例如,\x0A等价\n |
\uxxxx | 由十六进制xxxx指定的unicode字符,例如\u0009等价与\t |
\cX | 控制字符,如\cJ等价于换行符\n |
正则表达式的字符类
[...] | 方括号内的任意字符 |
[^...] | 除了方括号内的任意字符 |
[.] | 除换行和其他Unicode行终止符之外的任意字符 |
\w | 任何ASCII字符组成的单词,等价于[a-zA-Z0-9] |
\W | 非上 |
\s | 任何Unicode空白字符 |
\S | 非上 |
\d | 任何ASCII数字,等价[0-9] |
\D | 非上 |
[\b] | 退格直接量 |
在正则表达式中可以指定用于表示字符重复的标记,如下:
{n,m} | 匹配前一项至少n次,但不能超过m次 |
{n,} | 匹配前一项大于或等于n次 |
{n} | 匹配前一项n次 |
? | 匹配0或1次 |
+ | 匹配前一项1或多次 |
* | 匹配任意次 |
示例:
/\d{2,4}/
/\w{3}\d?/
/[^(]*/
非贪婪的重复:
上表中匹配重复字符时尽可能多地匹配,而且允许后续的正则表达式继续匹配,称之为贪婪的匹配。
我们同样可以在带匹配的字符后跟随一个问号表示非贪婪的匹配:??,+?,*?,{1,5}?。
如用/a+/来匹配aaa时,会匹配它的三个字符,而是用/a+?/只能匹配第一个a。
选择,分组,引用
“|” 用于分割供选择的字符
/ab|cd|ef/ 可以匹配ab或cd或ef 选择的顺序是从左到右,知道发现了匹配项,如果左边的选择项匹配,就忽略右边的,即使产生更好的匹配。
正则表达式的圆括号作用有多种,一个是把单独的项组合成子表达式,以便象处理独立的单元那样使用,“|”,“+”,“*”。
另外一个重要的作用是在完成的模式中定义子模式,当正则表达式成功的和目标字符串匹配时,可以从目标串中抽出和圆括号中的子模式相匹配的部分,在实际匹配过程中我们可以将真正关心的内容用括号括一起以便提取。
带圆括号的另一个用途是允许在同一个正则表达式的后部引用前面的子表达式。通过"\"加数字来实现。
例如下面的子表达式([Ss]cript)可以用\2来表示
/([Js]ava([Ss]cript)?)\sis\s(fun\w*)/
如果想要取出一段引号内的文本,
构造如下正则表达式:/['"]([^'"]*)['"]/ ,但是如果输入是‘hello,world”,也会匹配到,这不是想要的结果,但是如果用/['"]([^'"]*)\1/ 就可以了,因为存在这样的约束,就是左侧的引号和右侧的引号必须相匹配。
正则表达式的选择,分组和引用
| | 选择,匹配左边或右边的子表达式 |
(...) | 分组,将几个项合为一个单元,而且可以记住和这个组合相匹配的字符串以供此后的引用使用 |
(?:...) | 只组合,不会记忆与改组相匹配的字符 |
\n | 引用,和第n个分组第一次匹配的字符相匹配,组表示圆括号中的子表达式(也有可能是嵌套的)。 |
指定匹配的位置:
如果在符号“(?=)”和“)”之间加入一个表达式,它就表示一个先行断言,用以说明圆括号内的表达式必须正确匹配
带有“(?=)”和“)”表示正向先行断言
带有“(?!)”和“)”的断言表示负向先行断言
正则表达式的锚字符:
^ | 匹配字符串的开头 |
$ | 匹配字符串的结尾 |
\b | 匹配一个单词的边界 |
\B | 匹配非单词的边界 |
(?=p) | 零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符 |
(?!p) | 零宽负向先行断言,要求接下来的字符不与p匹配 |
javascript正则表达式的修饰符
i | 执行不区分大小的匹配 |
g | 执行一个全局的匹配,简而言之,即找到所有的匹配,而不是找到一个后就停止了 |
m | 多行匹配模式,如/java$/im可以匹配"java",也可以匹配"java\nisfun" |
String类的正则表达式的方法
String类支持4种使用正则表达式的方法:
search(regexp):返回第一个与之匹配的子串的起始位置,如果找不到,返回-1
replace(regexp,replaceStr):如果正则表达式设置了修饰符g,则会替换所有匹配的子串。如果在replaceStr中出现了$加数字,那么replace将会用指定的子表达式来替换这两个字符。例如:
var quote = /"([^"]*)"/g;
"javascript".replace(quote,'“$1”');
结果会将英文引号转换为中文引号。
match(regexp):返回由匹配结果组成的数组。 如果该正则表达式设置了修饰符g,那么返回的数组中包含所有匹配结果。如果正则表达式没有设置修饰符g,那么不会执行全局匹配,但是也会返回一个数组,第一个元素是初次匹配的子串,其后的数组元素为与圆括号括起来的子表达式相匹配的子串。
split(regexp):使用匹配的正则表达式结果将原字符串分割,返回分割后的结果。
RegExp对象
RegExp的属性:
global,表示是否有修饰符g
ignoreCase,表示是否有修饰符i
multiline,表示是否有修饰符m
lastIndex,如果有修饰符g,这个属性会存储下次开始匹配的位置。
RegExp的方法:
regexp.exec(str)方法,
exec(str)和str.match(regexp)的非全局匹配类似,匹配的结果返回一个数组,保存着匹配的字符串和括号中匹配的子串。但是它每执行一次,会改变lastIndex的值,下次执行的时候就从lastIndex开始执行。如果没有匹配到,则返回null。
test(str):当exec返回不是null的时候,他会返回true,当一个全局的正则表达式执行此方法时,它同样会改变lastIndex的值。