JavaScript 正则表达式学习笔记

本文最后更新于:2016年11月30日 晚上

创建一个正则表达式:

  • perl 风格
1
var expression = / parrern / flags

其中模式(parrern) 部分 可以使任何简单或复杂的正则表达式,每个正则表达式都可以带有一个或多个标志(flags),用以表明正则表达式的行为

  • JS 风格
1
var expression = new RegExp(“a”, “i”)

perl->flags 处 和 JS->new RegExp 第二个参数 的地方引用修饰符,修饰符可以单独使用,也可以组合使用.

** 匹配模式

有下列三个修饰符*(flags)*

  • g:表示全局模式,将应用于所有字符串,而非在发现第一个匹配项时立即停止.
  • i:表示不区分大小写
  • m:表示多行模式,即在到达一行文本末尾时还会继续查找下一行是否存在与模式匹配的项

当然如果想在表达式中增加匹配模式,这是需要用到

模式修改符

在正则表达式中间,对匹配模式进行修改。
修改后的匹配模式,只对当前小括号内,修改符之后的部分起作用。比如:

  • a(b(?i)c)d
    增加 i - IGNORECASE 模式,只对 c 起作用。表达式可以匹配 “abcd” 和 “abCd”

元字符

元字符 描述
. 查找单个字符,除了换行和行结束符。
\w 查找单词字符。
\W 查找非单词字符。
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。
\B 匹配非单词边界。
\0 查找 NUL 字符。
\n 查找换行符。
\f 查找换页符。
\r 查找回车符。
\t 查找制表符。
\v 查找垂直制表符。
\xxx 查找以八进制数 xxx 规定的字符。
\xdd 查找以十六进制数 dd 规定的字符。
\uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。

自定义字符集合(方括号)

[xyz]

一个字符集合。匹配方括号的中任意字符。你可以使用破折号(-)来指定一个字符范围。对于点(.)和星号(*)这样的特殊符号在一个字符集中没有特殊的意义。他们不必进行转意,不过转意也是起作用的。

例如,[abcd] 和[a-d]是一样的。他们都匹配”brisket”中得‘b’,也都匹配“city”中的‘c’。/[a-z.]+/ 和/[\w.]+/都匹配“test.i.ng”中得所有字符。

[^xyz]

“^” 符号代表”非,以外”.
一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。你可以使用破折号(-)来指定一个字符范围。任何普通字符在这里都是起作用的。

例如,[^abc] 和 [^a-c]
是一样的。他们匹配”brisket”中得‘r’,也匹配“chop”中的‘h’。

[0-9] 表示匹配0到9之间的数字.
[a-z] 表示匹配a-z之间的字母.

字符边界(空格)

一个词的边界就是一个词不被另外一个词跟随的位置或者不是另一个词汇字符前边的位置。注意,一个匹配的词的边界并不包含在匹配的内容中。换句话说,一个匹配的词的边界的内容的长度是0。
本身不匹配任何字符,只对字符边界和字符间缝隙附加条件的表达式。

边界条件 说明
^ 当前位置必须是文本开始位置
$ 当前位置必须是文本结束位置
\b 当前位置的左右两侧,只能有一侧是字母数字或下划线

n$ 匹配任何结尾为 n 的字符串。
^n 匹配任何开头为 n 的字符串。

分组(捕获组)与反向引用

用括号 ( ) 将其他表达式包含,可以使被包含的表达式组成一个整体,在被修饰匹配次数时,可作为整体被修饰。

另外,用括号包含的表达式,所匹配到的内容将单独作记录,匹配过程中或结束后可以被获取。

每一对括号会分配一个编号,使用 () 的捕获根据左括号的顺序从 1 开始自动编号。捕获元素编号为零的第一个捕获是由整个正则表达式模式匹配的文本。

  • (x) 匹配 x 并且捕获匹配项。 这被称为捕获括号(capturing parentheses)。

  • (?:x) 称之为非捕获括号,匹配’x’但是不记住匹配项。。匹配到的子字符串不能通过结果数组的[1],…,[n]进行访问。

匹配次数限定符,量词(数量词)

使被修饰的表达式可多次重复匹配的修饰符。

贪婪模式

  • 可使被修饰的表达式重复固定次数,也可以限定一定的重复匹配的次数范围。在限定符之后的表达式能够匹配成功的情况下,不定次数的限定符总是尽可能的多匹配。如果之后的表达式匹配失败,限定符可适当“让出”能够匹配的字符,以使整个表达式
    匹配成功。
限定符 说明
{n} 表达式固定重复n次,比如:”\w{2}” 相当于 “\w\w”
{m, n} 表达式尽可能重复n次,至少重复m次:”ba{1,3}”可以匹配 “ba”或”baa”或”baaa”
{m, } 表达式尽可能的多匹配,至少重复m次:”\w\d{2,}”可以匹配 “a12”,”x456”…
? 表达式尽可能匹配1次,也可以不匹配,相当于 {0, 1}
+ 表达式尽可能的多匹配,至少匹配1次,相当于 {1, }
* 表达式尽可能的多匹配,最少可以不匹配,相当于 {0, }

勉强模式

  • 在限定符之后添加问号(?),则使限定符成为“勉强模式”。勉强模式的限定符,总是尽可能少的匹配。如果之后的表达式匹配失败,勉强模式也可以尽可能少的再匹配一些,以使整个表达式匹配成功。
限定符 说明
{m, n}? 表达式尽量只匹配m次,最多重复n次。
{m, }? 表达式尽量只匹配m次,最多可以匹配任意次。
?? 表达式尽量不匹配,最多匹配1次,相当于 {0, 1}?
+? 表达式尽量只匹配1次,最多可匹配任意次,相当于 {1, }?
*? 表达式尽量不匹配,最多可匹配任意次,相当于 {0, }?

占有模式

  • 在限定符之后添加加号(+),则使限定符成为“占有模式”。占有模式的限定符,总是尽可能多的匹配。与“贪婪模式”不同的是,即使之后的表达式匹配失败,“占有模式”也不会“让出”自己能够匹配的字符。
限定符 说明
{m, n}+ 表达式尽可能重复n次,至少重复m次。
{m, }+ 表达式尽可能的多匹配,至少重复m次。
?+ 表达式尽可能匹配1次,也可以不匹配,相当于 {0, 1}+
++ 表达式尽可能的多匹配,至少匹配1次,相当于 {1, }+
*+ 表达式尽可能的多匹配,最少可以不匹配,相当于 {0, }+

选择表达式 xxx | xxx

使用竖线 “|” 分隔多段表达式,整个表达式可匹配其中任意一段。
正则引擎总是从左向右进行尝试匹配,如果每一段表达式都匹配失败,则整个表达式匹配失败。

条件表达式

根据某个条件是否成立,来选择匹配 2 个可选表达式中的其中一个。

  • (?(1)yes|no)

条件为数字分组1如果有捕获,则进行 yes 部分匹配,否则 no 部分

替换语法

Replace替换操作
对匹配到的字符串进行替换操作。

字符 解释
$1 ~ $999 代表某个捕获组捕获到的内容。如果捕获组编号大于表达式中的最大捕获组编号,那么 DEELX 会减少数字个数,以使捕获组编号小于或等于最大编号;而把剩余的数字看作字符串常量。举例:当前最大捕获组编号为 20,那么,指定替换为 “$999” 将被看作 “$9” + “99”;指定替换为 “$15” 将代表第 15 个捕获组。如果本来就是想把 “5” 当成字符串常量时(”$1” + “5”),可以使用 $0015 表示,DEELX 最多识别 3 位 10 进制数字。
${name} 代表指定命名分组捕获到的内容。
$$ 表示一个 $ 符号。
$& 代表每次匹配到内容。
$` 代表原字符串中,匹配到的内容之前的字符串。$符号就是键盘左上角”~”下边的那个符号。
$’ 代表原字符串中,匹配到的内容之后的字符串。$’ 中 ‘ 符号就是单引号。
$+ 代表所有“有捕获”的分组中,编号最大的那个分组。举例:”aaa(b+)ccc(b+)” 在匹配”aaabbb”时,虽然最大分组是第2个分组,但最大“有捕获”的是第1个分组,此时的 $+ 代表 $1
$_ 代表被替换的整个字符串。”_” 是下划线。

用法请看下方replace 方法

注释

格式 (?# xxx ) 可用来表示一段注释。
1.注释可以位于表达式中任意地方
2.在 (?# 之后,遇到第一个反括号将表示注释结束。

实例属性

1.global

  • 是否开启全局匹配,也就是匹配目标字符串中所有可能的匹配项,而不是只进行第一次匹配。
    2.ignoreCase
  • 在匹配字符串时是否要忽略字符的大小写。
    3.lastIndex
  • 下次匹配开始的字符串索引位置。
    4.multiline
  • 是否开启多行模式匹配(影响 ^ 和 $ 的行为)。
    5.source
  • 正则对象的源模式文本。

RegExp 构造函数属性

长属性名 短属性名 说明
input $_ 最近一次要匹配的字符串
lastMarch $& 最近一次的匹配项
lastParen $+ 最近一次匹配的捕获组
leftContext $` input 字符串中lastMatch 之前的文本
leftContext $` input 字符串中lastMatch 之前的文本
rightContext $’ input字符串中lastMatch之后的文本

例子

1
2
3
4
5
6
7
8
9
10
var text = "this has been a short summer";
var pattern = /(.)hort/g;
if (pattern.test(text)){
alert(RegExp.input); //this has been a short summer
alert(RegExp.leftContext); //this has been a
alert(RegExp.rightContext); // summer
alert(RegExp.lastMatch); //short
alert(RegExp.lastParen); //s
alert(RegExp.multiline); //false
}

1
2
3
4
5
6
7
8
9
10
var text = "this has been a short summer";
var pattern = /(.)hort/g;
if (pattern.test(text)){
alert(RegExp.$_); //this has been a short summer
alert(RegExp["$`"]); //this has been a
alert(RegExp["$'"]); // summer
alert(RegExp["$&"]); //short
alert(RegExp["$+"]); //s
alert(RegExp["$*"]); //false
}

等价


模式匹配的String方法

search方法

与第一个与 regexp 相匹配的子串的起始位置。
如果没有找到任何匹配的子串,则返回 -1。

1
2
var str="123124145adasdqwri"
document.write(str.search(/dasd/))

match方法

可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
返回匹配的值

1
2
3
4
5
6
7
8
var str="Hello world!"
document.write(str.match("world") + "<br />")//world
document.write(str.match("World") + "<br />")//null
document.write(str.match("worlld") + "<br />")//null
document.write(str.match("world!"))///world!

var str="1 plus 2 equal 3"
document.write(str.match(/\d+/g))//1,2,3

split方法

分割
字符串方法,可用正则表达式,

1
2
var words = sentence.split(' ')
var words = sentence.split(/\s+/)

replace方法

还有9个用于存储捕获组”(x)” 的构造函数属性,访问的方法是 RegExp.$1, RegExp.$2,RegExp.$3…. 也可省略RegExp 在调用exec() 或 test() 方法时,这些属性会自动填充,

PS:用来存储”()”捕获组里匹配到的值.

1
2
3
4
5
6
var text = "this has been a short summer";
var pattern = /(..)or(.)/g;
if (pattern.test(text)){
alert(RegExp.$1); //sh
alert(RegExp.$2); //t
}
1
2
3
4
var re =/(\w+)\s(\w+)/;
var str ="John Smith";
var newstr = str.replace(re,"$2, $1");
print(newstr);//Smith John

reg对象exec()方法

检索字符串中指定的值。返回找到的值,并确定其位置。和match()类似,但是更加强大.此方法有自己的属性

属性/索引 描述 例子
[0] 匹配的全部字符串 Quick Brown Fox Jumps
[1], …[n ] 括号中的分组捕获 [2] = Jumps [1] = Brown
index 匹配到的字符位于原始字符串的基于0的索引值 4
input 原始字符串 The Quick Brown Fox Jumps Over The Lazy Dog
lastIndex 下一次匹配开始的位置 25
ignoreCase 是否使用了’i’标记使正则匹配忽略大小写 true
global 是否使用了’g’标记来进行全局的匹配. true
multiline 是否使用了’m’标记使正则工作在多行模式(也就是,^ 和 $)可以匹配字符串中每一行的开始和结束(行是由 \n 或 \r 分割的),而不只是整个输入字符串的最开始和最末尾处。) false
source 正则模式的字符串 quick\s(brown).+?(jumps)
1
2
3
4
5
6
7
8
var myRe = /ab*/g;
var str = 'abbcdefabh';
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
var msg = 'Found ' + myArray[0] + '. ';
msg += 'Next match starts at ' + myRe.lastIndex;
console.log(msg);
}

reg对象test()方法(最常用)

检索字符串中指定的值。返回 true 或 false。

1
2
3
4
var str = "Visit W3School";
var patt1 = new RegExp("W3School");
var result = patt1.test(str);
document.write("Result: " + result);//true

常用正则表达式

  • 正整数
    /^[0-9][1-9][0-9]$/;
  • 负整数
    /^-[0-9][1-9][0-9]$/;
  • 正浮点数
    /^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9]))$/;
  • 负浮点数
    /^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])))$/;
  • 浮点数
    /^(-?\d+)(.\d+)?$/;
  • email地址
    /^[\w-]+(.[\w-]+)*@[\w-]+(.[\w-]+)+$/;
  • url地址
    /^[a-zA-z]+://(\w+(-\w+))(.(\w+(-\w+)))(?\S)?$/;
    或:^http://[A-Za-z0-9]+.[A-Za-z0-9]+[/=?%-&_~`@[]':+!]([^<>""])$
  • 年/月/日(年-月-日、年.月.日)
    /^(19|20)\d\d- /.- /.$/;
  • 匹配中文字符
    /[\u4e00-\u9fa5]/;
  • 匹配帐号是否合法(字母开头,允许5-10字节,允许字母数字下划线)
    /^[a-zA-Z][a-zA-Z0-9_]{4,9}$/;
  • 匹配空白行的正则表达式
    /\n\s*\r/;
  • 匹配中国邮政编码
    /[1-9]\d{5}(?!\d)/;
  • 匹配身份证
    /\d{15}|\d{18}/;
  • 匹配国内电话号码
    /(\d{3}-|\d{4}-)?(\d{8}|\d{7})?/;
  • 匹配IP地址
    /((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/;
  • 匹配首尾空白字符的正则表达式
    /^\s*|\s*$/;
    //匹配HTML标记的正则表达式
    < (\S*?)[^>]>.?|< .*? />;
  • sql 语句
    ^(select|drop|delete|create|update|insert).*$
  • 提取信息中的网络链接
    (h|H)(r|R)(e|E)(f|F) *= *(‘|”)?(\w|\|/|.)+(‘|”| *|>)?
  • 提取信息中的邮件地址
    \w+([-+.]\w+)*@\w+([-.]\w+).\w+([-.]\w+)
  • 提取信息中的图片链接
    (s|S)(r|R)(c|C) *= *(‘|”)?(\w|\|/|.)+(‘|”| *|>)?
  • 提取信息中的 IP 地址
    (\d+).(\d+).(\d+).(\d+)
  • 取信息中的中国手机号码
    (86)013\d{9}
  • 提取信息中的中国邮政编码
    [1-9]{1}(\d+){5}
  • 提取信息中的浮点数(即小数)
    (-?\d*).?\d+
  • 提取信息中的任何数字
    (-?\d*)(.\d+)?
  • 电话区号
    ^0\d{2,3}$
  • 腾讯 QQ 号
    ^[1-9][1-9][0-9]$
  • 帐号(字母开头,允许 5-16 字节,允许字母数字下划线)
    ^[a-zA-Z][a-zA-Z0-9_]{4,15}$
  • 中文、英文、数字及下划线
    ^[\u4e00-\u9fa5_a-zA-Z0-9]+$

正则脑图

正则脑图

参考链接


JavaScript 正则表达式学习笔记
https://www.zwjay.cn/2016/03/25/2016-03-25-RegExp/
作者
Mr.Jaxson
发布于
2016年3月25日
许可协议