正则表达式基础

参考:
网易云课堂(链接已失效,原文贴在最后面)
重新拎一遍js的正则表达式


我个人对正则表达式是这么看的,首先这是一个规则,按照一定的格式来进行匹配;其次,这些规则中包含了有元字符(即一系列有特殊指向的关键字),字符类(具有一定匹配规则的类型),量词(用来修饰规则的次数),修饰符(对规则进行进一步的限制)。

不过这几种划分主要来源于上述提到的在网易云课堂中看到的分享,实际上正则表达式的符号不一定完全能对的上号。

一般规则

  • 在一对/ /中输入要匹配的字符即可进行匹配
    • 在js中,RegExp的实例通过exec和test方法进行匹配
1
2
3
var pattern = /regexp/;
var str = "123regexp456";
pattern.test(str); //true
  • 因为不少字符在正则表达式中是由特殊作用的,所以要通过\进行转义

元字符

元字符即特殊的关键字,这些关键字代表着可以匹配到的特定字符
其中大写的\B \D \S \W表示的意思与小写相反

  • \b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
  • \B 匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
  • \d 匹配一个数字字符。等价于 [0-9]。
  • \D 匹配一个非数字字符。等价于 [^0-9]。
  • \f 匹配一个换页符。等价于 \x0c 和 \cL。
  • \n 匹配一个换行符。等价于 \x0a 和 \cJ。
  • \r 匹配一个回车符。等价于 \x0d 和 \cM。
  • \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
  • \S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
  • \t 匹配一个制表符。等价于 \x09 和 \cI。
  • \v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
  • \w 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’。
  • \W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。

字符类

使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。用 [^ ] 包含一系列字符,则能够匹配其中字符之外的任意一个字符。

  • [ab5@] 匹配 “a” 或 “b” 或 “5” 或 “@”
  • [^abc] 匹配 “a”,”b”,”c” 之外的任意一个字符
  • [f-k] 匹配 “f”~”k” 之间的任意一个字母
  • [^A-F0-3] 匹配 “A”~”F”,”0”~”3” 之外的任意一个字符

  • 表达式 “[bcd][bcd]” 匹配 “abc123” 时,匹配的结果是:成功;匹配到的内容是:”bc”;匹配到的位置是:开始于1,结束于3

量词

  • {n} 表达式重复n次,比如:”\w{2}” 相当于 “\w\w”;”a{5}” 相当于 “aaaaa”
  • {m,n} 表达式至少重复m次,最多重复n次,比如:”ba{1,3}”可以匹配 “ba”或”baa”或”baaa”
  • {m,} 表达式至少重复m次,比如:”\w\d{2,}”可以匹配 “a12”,”_456”,”M12344”…
  • ? 匹配表达式0次或者1次,相当于 {0,1},比如:”a[cd]?”可以匹配 “a”,”ac”,”ad”
  • + 表达式至少出现1次,相当于 {1,},比如:”a+b”可以匹配 “ab”,”aab”,”aaab”…
  • * 表达式不出现或出现任意次,相当于 {0,},比如:”\^*b”可以匹配 “b”,”^^^b”…

修饰符

  • ^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。
  • $ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。
  • * 匹配前面的子表达式零次或多次。例如,zo 能匹配 “z” 以及 “zoo”。 等价于{0,}。
  • . 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,需要使用 ‘[.\n]’ 的模式。
  • g 全局匹配
  • i 忽略大小写
  • | 匹配之前或者之后的两项例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。
  • (?:) 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。
    (?=)正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。
  • (?!) 负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。

其他规则

1.贪婪模式与非贪婪模式
默认会尽可能多的匹配
在量词后面使用则会尽可能少的匹配

尽可能多的匹配
var text = “abbbbbba”;
var ptn = /(a)(\w+)/;
可以匹配到abbbbbba, a, bbbbba

尽可能少的匹配
var text = “abbbbbba”;
var ptn = /(a)(\w+?)/;
可以匹配到ab, a, b

2.反向引用
\1
\2

3.预搜索 反向预搜索
正向
(?=xxx)
(?!xxx)

反向
(?<=xxx)
(?<!xxx)
JScript.RegExp 不支持反向预搜索


正则表达式是一种表达字符串格式的表达式,主要用来匹配某类字符串,在各种语言都有实现。枯燥的教义之后,我们来看js中正则表达式的例子。
js中常用 /某种格式/ 来表示正则表达式。

  1. 比如 /phone/ 表示包含’phone’字符串,那么 /phone/.test(‘My phone number is 13111456788’) 当然返回true, 因为 ‘My phone number is 13111456788’字符串中包含’phone’字符
  2. 现在我要把 ‘My phone number is 13111456788’ 中的手机号码替换成 ‘就不告诉你’
    我当然可以这么做 ‘My phone number is 13111456788’ .replace(/13111456788/, ‘就不告诉你’); 当然返回 “My phone number is 就不告诉你”
  3. 对于一个有逼格的程序员,上面的实现方式明显太low了,如果字符串中出现的是其他手机号码而不是”13111456788”,作为一个有逼格的程序员至少也要搞出能替换所有手机号码的程序嘛,于是我们需要一个牛B的东西叫做 字符类,故名思议它能表示一类字符,比如[0-9] (字符类的语法是 [字符类包含的字符])表示数字,使用字符类我们升级下逼格:
    ‘My phone number is 13111456788’ .replace(/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/, ‘就不告诉你’);
  4. [0-9]有5个字符,写起来不爽,我们引入元字符,元字符是预定义的特殊字符,其中 \d 表示数字等价于[0-9],使用元字符我们升级下逼格:
    ‘My phone number is 13111456788’ .replace(/\d\d\d\d\d\d\d\d\d\d\d/, ‘就不告诉你’);
  5. 什么我们的代码中出现了11个\d, 码农教义第一条 Don’t Repeat Yourself ,你都不知道嘛。为了进一步提高逼格,我们需要另个一牛B的东西叫做 量词,顾名思义是表示数量,使用量词{11}(表示出现11次)我们再升级下逼格:
    ‘My phone number is 13111456788’ .replace(/\d{11}/, ‘就不告诉你’);
  6. 假如我有两个电话号码,’My phone number is 13111456788 and 13563546782’ 那么
    ‘My phone number is 13111456788 and 13563546782’ .replace(/\d{11}/, ‘就不告诉你’);
    运行结果为: “My phone number is 就不告诉你 and 13563546782”
    啊,我想都不告诉你,怎么还告诉你 13563546782,这个时候我们需要另一个牛B的东西修饰符,我们使用 g (表示所有匹配的字符串),使用修饰符我们升级下逼格:
    ‘My phone number is 13111456788 and 13563546782’ .replace(/\d{11}/g, ‘就不告诉你’);

以上我们把正则表达式最主要的特性,基本串起来的,正则表达式里面还有很多其他的字符类,元字符,量词,修饰符等,我这边抛个砖,希望大家参与讨论当中。