正则表达式
Posted redo19990701
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式相关的知识,希望对你有一定的参考价值。
正则表达式的概念
- 使用单个字符串来描述,匹配一系列符合某个句法规则的字符串.
元字符
元字符 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
w | 匹配字母或数字或下划线 |
s | 匹配任意的空白符 |
d | 匹配数字 |
匹配单词开始或者结尾 | |
^ | 匹配单词开始 |
$ | 匹配字符串的结束 |
特殊字符
特别字符 | 描述 |
---|---|
$ | 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘ ‘ 或 ‘ ‘。要匹配 $ 字符本身,请使用 $。 |
( ) | 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。 |
* | 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。 |
+ | 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。 |
. | 匹配除换行符 之外的任何单字符。要匹配 . ,请使用 . 。 |
[ | 标记一个中括号表达式的开始。要匹配 [,请使用 [。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。 |
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n‘ 匹配字符 ‘n‘。‘ ‘ 匹配换行符。序列 ‘‘ 匹配 "",而 ‘(‘ 则匹配 "("。 | |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 ^。 |
{ | 标记限定符表达式的开始。要匹配 {,请使用 {。 |
| | 指明两项之间的一个选择。要匹配 |,请使用 |。 |
反义
语法 | 说明 |
---|---|
W | 匹配任意不是字母,S数字,下划线的字符 |
S | 匹配任意不是空白符的字符 |
D | 匹配任意非数字的字符 |
B | 匹配不是单词开头和结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^one] | 匹配除了one这几个字母的任意字符 |
字符转义
- 如果要匹配.?之类的符号使用转移
重复模式
- 重复后什么也不加--贪婪模式
- 重复后加?--懒惰模式
语法 | 说明(和之前紧邻元素组合起来表示之前紧邻元素出现次数) |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
分支条件
- 用|把不同的规则分隔开
- 从左到右地测试每个条件,如果满足某个分支的话就不去管其它的条件
字符类
- [0-9]==d
- [a-z0-9A-Z]==w
- [&?.]
- []
- .==[^ ]
括号的作用
- 限制多选项的范围
- 将若干个字符组合为一个单元,受*?+量词作用
- 记忆包含的文本
非捕获型括号
- (?:)不会记忆该括号中的内容,不会产生$
反向引用
- 用括号括起来的内容可以被记忆,可以使用序列12来匹配前面括号匹配中的文本,数字取决于是第几个括号
- 分组命名(?<name>exp)
环视功能
环视功能不匹配任何字符,只匹配文本中的特定位置,这一点与单词分界符「」、锚点「^」和「$」相似。但是,环视比它们更加通用。
环视不会占用字符
环视类型
- 顺序环视(?=...),从左至右匹配位置.该位置右边是...
- 逆序环视(?<=...),从右向左匹配位置.该位置左边是...
实例:(?=Jeffrey)Jeff可以匹配by Thomas Jeffery,不可以匹配Jefferson,因为(?=Jeffery)无法找到位置.
(?<=Jeff)(?=s)匹配Jeff(位置)s 顺序环视和逆序环视前后顺序是无关紧要的
类型 正则表达式 匹配成功的条件 肯定顺序环视 (?=...) 子表达式可以匹配右侧文本 肯定逆序环视 (?<=...) 子表达式可以匹配左侧文本 否定顺序环视 (?!...) 子表达式不可以匹配右侧文本 否定逆序环视 (?<!...) 子表达式不可以匹配左侧文本
元字符优先级
运算符 | 描述 |
---|---|
转义符 | |
(), (?:), (?=), [] | 圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m} | 限定符 |
^, $, 任何元字符、任何字符 | 定位点和序列(即:位置和顺序) |
| | 替换,"或"操作 字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。 |
平衡组//递归匹配
- (?‘group‘)把捕获的内容命名为group并且压入堆栈.
- (?‘-group‘)从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则匹配失败.
- (?(group)yes|no)如果堆栈上存在以group为名的捕获内容,继续匹配yes的内容,反之匹配no的内容.
- (?!)零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败.
经验之谈
- .*会一直匹配到一行的结束,如果不需要匹配反斜线,可以将每个点号替换为"[^ \]"
- 处理各种极端情况会降低成本/收益的比例,合适的做法就是不依赖于正则表达式,可以用括号将每个字段括起来,把数字变成程序中的$1,$2,$3,然后进行检验.
- 多选结构应将可能匹配次数多的子表达式放到前面,以减少回溯.
- 加号和星号不要作用于一个元素,会产生大量回溯.
效率
- 消除不必要的括号和字符组
- 不确定的字符用量词优化,确定的字符不要用两次优化.ddd<d{3};111>1{3}.
- 使用非捕获型括号时,字符串结束/行锚点优化会被关闭.(000|999)$>(?:000|999).
- 使用非捕获型括号不但能够提高速度,而且会减少回溯使用的状态的数量.
- 使用锚点^或$,最好将锚点提取出来
- 从量词中提取必须的元素,xx*代替x+,或者用----{0,2}代替-{4,6}.
- 减少匹配长度
实例
- IP--------------------------------(1?d?d|2[0-4]d|25[0-5]).(1?d?d|2[0-4]d|25[0-5]).(1?d?d|2[0-4]d|25[0-5]).(1?d?d|2[0-4]d|25[0-5])
- .*单个字符匹配任意次,贪婪匹配.
- .*?满足情况的最小匹配,懒惰匹配.
- 匹配html的tag---------------------------------<("[^"]*"|‘[^‘]*‘|[^‘">])*>即<"文本">或<‘文本‘>或<文本>
以上是关于正则表达式的主要内容,如果未能解决你的问题,请参考以下文章