- JS 正则 方案
- 基本字符
- 字面量
- /^[a-z]+$/.text(str); # ^代表开头, $是结尾
- 转义
- 元字符 # metacharacter
- .
- \b
- 表示单词的开头或结尾,也就是单词的分界。只匹配一个位置\s\S
- \bhi\b
- \d
- \s
- 匹配任意空白符,包括空格、tab、换行、中文全角空格等
- \s\S
- \w
- ^
- $
- 反义
- 非
- [^x]
- 非x, [^aeiou] 除了aeiou以外的任意字符
- 限定字符
- {2}
- 表示前面的内容出现2次, {5, 12}内容出现5到12次, {5, }内容出现5或更多次
- ?
-
-
- 字符类
- 分枝条件
- | # jpg|png,
- 每个分支都从第一个分支开始匹配, 如\d{5}|\d{5}-d{4}只能匹配11111或11111-2222中的11111
- 分组 # 零宽断言只占用不消费
- ()
- 语法
- (exp)
- (?exp) # 组命名
- (?:exp) # 消费exp, 不捕获匹配的文本,也不分配组号
- (?=exp) # 零宽断言,正向前瞻,后面能匹配表达式exp
- \b\w+(?=ing\b) # 匹配以ing结尾单词的前面部分,如dancing中的danc
- /(\w)\1{2}(?=(\w)\2{2})/g # 匹配所有在3个连续相同字符前的相邻3个连续相同字符, aaalllsss0tAAAnnn999结果是aaa, lll, AAA, nnn
- (?⇐exp) # 零宽断言,正向后瞻,前面能匹配表达式exp
- (?⇐\bre)\w+\b # 匹配以re开头单词的后半部分,如reading中的ading
- (?!exp) # 零宽断言,负向前瞻,后面不匹配exp的位置, js不支持
- \b\wq(?!u)\w\b # 匹配一个单词,该单词包含后面不是字母u的字母q
- \d{3}(?!\d) # 匹配三位数字,且它们后面不能有数字
- \b((?!abc)\w)+\b # 匹配不包含连续字符串abc的单词
- (?<!exp) # 零宽断言,负向后瞻,前面不匹配exp的位置, js不支持
- (?<![a-z])\d{7} # 匹配前面不是小写字母的七位数字
(?#comment) # 注释
- 后向引用 # 分组捕获后会自动编号,从左到右,1234。后向引用用于引用前面匹配到的文本,如 \1 代表分组1匹配的文本
- \b(\w+)\b\s+\1\b # 匹配重复的单词, 如go go
- (?\w+) 或 (?’Word’\w+) # 把\w+的组名指定为Word, 用\k引用
- 贪婪与懒惰
- 包含能接受重复限定符时,会匹配尽可能多的字符。如a.*b
- a.*?b会懒惰匹配
- 懒惰限定符
- ? 重复懒惰匹配任意次
- +? 重复懒惰匹配1次或多次
- ?? 重复懒惰匹配0次或1次
- {n, m}? 重复懒惰匹配n到m次
- {n,}? 重复懒惰匹配n次以上
- 平衡组/递归匹配
- (?‘group’) 把捕获的内容命名为group,并压入栈(Stack)
- (?’-group’) 从栈中弹出最后压入的名为group的捕获内容。如果栈为空,则匹配失效
- (?(group)yes|no) 如果栈中存在名为group的捕获内容,继续匹配yes部分的表达式,否则则继续匹配no部分的表达式
- 示例 # 平衡组最常见的应用是匹配HTML
- 匹配xx<aaaa>yy
- 思路
- 每碰到左括号,就压入一个Open, 每碰到右括号,弹出一个
- 最后看栈是否空,如果否则表示不配对,应该失败
- 正则表达式引擎会进行回溯(放弃最前面或最后面一些字符), 尽量使整个表达式得到匹配
- < # 最外层的左括号 - [^<>]* # 后面非括号的内容
- (
- (
- (?’Open’<) # 又碰到了左括号, 压入一个Open
- [^<>]* # 后面非括号内容
- )+
- (
- (?’-Open’>) # 碰到了右括号, 擦掉一个Open
- [^<>]* # 后面非括号内容
- )+
- )*
- (?(Open)(?!)) # 负向前瞻,判断栈中还有没有Open, 有则匹配失败
> # 最外层右括号
- )
- 特点
- js中不支持 回顾后发断言
- 可以跟三个flag,比如/something/igm
- i表示不区分大小写
- g表示匹配多个
- g会影响String.prototype.match()和RegExp.prototype.exec()的行为
- match中加g会返回数组,不加g返回比较详细的信息
- exec中加g,且正则存在变量中时,该正则变量执行exec后会存储信息, 如
- var re = /h(.*?)\b/g;
- re.exec(‘hello helloo’) 执行三次,匹配内容有变化
- m表示,^$可以匹配每一个的开头和结尾
- api
- RegExp
- exec # 执行第一个, exp本身保留执行状态
- test
- String
- replace # 替换第一个, ‘abc - 123 - #$*’
-
'John Smith'.replace(/(\w+)\s(\w+)/, '$2, $1')
'abc123#$*'.replace(/([^\d]*)(\d*)([^\w]*)/, function replacer(match, p1, p2, p3, offset, string) {
return [p1, p2, p3].join(' - ');
});
- replaceAll
- match # 不能有g选项,只得到第一个匹配
- .net中处理选项
- IgnoreCase
- Multiline
- 多行模式, 更改^$的含义为一行首和行尾, $表示\n之前的位置以及字符串结束前的位置
- Singleline
- 单行模式(可以与Multiline通用),更改.的含义,便它与每一个字符匹配(包括\n)
- IgnorePatternWhitespace
忽略空白,会忽略表达式中非转义空白并启用#作为标记注释
- ExplicitCapture
- 元字符扩展
- \a # 报警字符
- \t # 制表符
- \v # 竖向制表符
- \r # 回车
- \f # 换页符
- \n # 换行符
- \e # Escape
- \0nn # ASCII码中八进制代码为nn的字符
- \xnn # ASCII码中十六进制代码为nn的字符
- \unnnn # Unicode码中十六进制代码为nnnn的字符
- \cN # ASCII控制字符,如\cC 代表ctrl + c
- \A # 字符串开头,同^但不受多行选项影响
- \Z # 字符串结尾或行尾,不受多行选项影响
- \z # 字符串结尾,同$但不受多行选项影响
- \G # 当前搜索的开头
- \p{name} # Unicode中命名为name的字符类,如\p{IsGreek}
- (?>exp) # 贪婪子表达式
- (?-exp) # 平衡组
- (?im-nsx:exp) # 在子表达式exp中改变处理选项
- (?im-nsx) # 为表达式后面的部分改变处理选项
- (?(exp)yes|no) # 把exp当作零宽正向先行断言,如果能匹配,使用yes作为此组表达式,否则使用no
- (?(exp)yes) 只使用空表达式为no
- (?(name)yes|no) 命名为name的组捕获到内容,使用yes