正则表达式(详解)

171 阅读4分钟

1. 构造正则表达式

/expression/

  • 正则表达式示例:
    • /^\s*$/ 匹配空行
    • /\d{2}-\d{5}/ 匹配由两位数 - 五位数 组成的ID号
  • 普通字符

最简单的正则表达式是与搜索的字符串相比较的单个普通字符。如单字符正则表达式A始终会匹配字母A,无论其会出现在搜索字符串的哪个位置。

    • /a/
    • /7/
    • /M/

2. 正则表达式语法

特殊字符(常用)

*:零次或多次匹配前面字符或子表达式。等价与{0,}

+:一次或多次匹配前面的字符或子表达式。等价于{1,}

?:零次或一次匹配前面的字符或子表达式。等价于{0,1} (当?紧跟任何限制符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是非贪婪的。非贪婪模式匹配搜索到的,尽可能少的字符串,而默认的贪婪模式匹配搜索到的,尽可能多的字符串)

^:匹配搜索字符串的开始位置/取反操作

$:匹配搜索字符串结尾的位置

. :匹配除换行符\n之外的任何单个字符

[]:标记括号表达式的开始和结尾

{}:标记限定符的开始和结尾

():标记子表达式的开始和结尾

|:指示在两个或多个项之间进行选择

/:表示js中的文本正则表达式的开始或结尾

\:将下一个字符标记为特殊字符、文本、反向引用、八进制转义符

元字符

\d:数字字符匹配,等效于[0-9]

\D:非数字字符匹配,等效于^[0-9]

\w:与以下任意字符匹配:A-Z、a-z、0-9 和下划线,等效于[A-Za-z0-9_]

\W:与除A-Z、a-z、0-9、和下划线以外的任意字符匹配,等效于 [^A-Za-z0-9_]

[x,y,z]:字符集。与任何一个指定字符匹配

[^xyz]:反向字符集,与未指定范围内的任何一个字符匹配

[a-z]:字符范围,匹配指定范围内的任何字符

[^a-z]:反向字符范围,与不在指定范围内的任何字符匹配。 匹配任意字符

{n}: 正好匹配 n 次。 n 是非负整数

{n,}:至少匹配 n 次。 n 是非负整数

{n,m}:匹配至少 n 次,至多 m 次。 n 和 m 是非负整数,其中 n <= m。 逗号和数字之间不能有空格

限定符

*:零次或多次匹配前面字符或子表达式。等价与{0,}

+:一次或多次匹配前面的字符或子表达式。等价于{1,}

?:零次或一次匹配前面的字符或子表达式。等价于{0,1} (当?紧跟任何限制符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是非贪婪的。非贪婪模式匹配搜索到的,尽可能少的字符串,而默认的贪婪模式匹配搜索到的,尽可能多的字符串)

优先级

3. 正则表达式编程

搜索 exec()

语法:regexp.exec(str)

exec()函数用于检索字符串中正则表达式的匹配

如果有匹配的值则返回该函数的值,如果没有则返回null。

替换 replace()

语法:str.replace(regexp|substr,newSubstr,function)

  • 参数1,匹配条件:正则表达式、字符串
    • 如果是字符串,仅匹配一次
    • 如果是正则表达式,没有全局标记g和分组的时候,也是只匹配一次;如果有全局标记g的话是进行全局多次匹配的。
  • 参数2,替换字符、方法
    • 注意:当替换字符插入特殊变量名

    • 当参数是函数的时候,则是用函数的返回值进行替换
提取 match()

签名:match([string] | [RegExp])

  • 参数:既可以是一个字符串,也可以是一个正则表达式、该方法绝大多数是要使用正则表达式。这里仅考虑参数是正则表达式.
  • 返回值:数组或者null
  • 注意点,正则表达式要用 /.../ 包裹起来
  • 补充:match()返回指定字符串;search()返回指定字符串首次出现的位置
不使用全局匹配时(不使用g)

match()方法只找到源字符串中首次匹配的子串后,就立即得到返回结果,不再比较之后的剩余的部分是否还有匹配上的内容(一个数组,有匹配值,index,input)

使用全局匹配时(使用g)

在字符串str中匹配出所有的由数字组成的字符串(一个数组,只有匹配值)

使用分组(不使用g)

该正则表达式为: /\d(th)/ ,该表达式中使用了小括号(),在此次的作用为分组。所以match()的结果是带有分组特征的。返回的数组包含多个元素,第一个元素是以贪婪模式找到的最长的匹配,之后的元素一次为该匹配中的第一、第二、第三...个分组,这里只有一个分组,所以也就只匹配到一个分组结果,也就是'th'。

但当正则表达式改为: /\d+(t)(h)/ ,匹配到的项就有3个,分别是 '286th'、't'、'h'

使用分组(使用g)

进行分组全局匹配,即使有分组的存在,在匹配结果中只有匹配到的最长的,那些分组的子匹配都不见了。

表现为:这次匹配到的结果是'286th'和'108th',只要使用了全局匹配模式,那么match()只返回"贪婪"的匹配结果。这里的"贪婪"指的是只招那个最长的能匹配上的字符串,至于分组项就忽略了

compile

将正则表达式编译为内部格式,从而更快地执行

test

语法:regexp.test(string)

测试搜索字符串内是否存在模式,

用于检测一个字符是否匹配某个模式,如果匹配则返回true,不匹配则返回false

search

返回首个匹配项的位置

用于检索字符串中指定的子字符串,或检索与正则表达式想匹配的子字符串,若找到返回下标,若找不到返回-1。

标记 Flags
g:全局匹配,匹配所有项
i:搜索不区分大小写
m:^ 匹配 \n 或 \r 之后的位置;$ 匹配 \n 或 \r 之前的位置

但无论 m 标记是否存在,^ 均匹配搜索字符串开头的位置,而 $ 均匹配搜索字符串结尾的位置。