目录
- 正则表达式的概念
- 元字符
- 特殊字符
- 反义
- 字符转义
- 重复模式
- 分支条件
- 字符类
- 括号的作用
- 非捕获型括号
- 反向引用
- 环视功能
- 元字符优先级
- 平衡组//递归匹配
- 经验之谈
- 效率
- 实例
正则表达式的概念
- 使用单个字符串来描述,匹配一系列符合某个句法规则的字符串.
元字符
. |
匹配除换行符以外的任意字符 |
w |
匹配字母或数字或下划线 |
s |
匹配任意的空白符 |
d |
匹配数字 |
b |
匹配单词开始或者结尾 |
^ |
匹配单词开始 |
$ |
匹配字符串的结束 |
特殊字符
$ |
匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘n‘ 或 ‘r‘。要匹配 $ 字符本身,请使用 $。 |
( ) |
标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。 |
* |
匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。 |
+ |
匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。 |
. |
匹配除换行符 n 之外的任何单字符。要匹配 . ,请使用 . 。 |
[ |
标记一个中括号表达式的开始。要匹配 [,请使用 [。 |
? |
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。 |
|
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n‘ 匹配字符 ‘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
- [&?.]
- []
- .==[^n]
括号的作用
- 限制多选项的范围
- 将若干个字符组合为一个单元,受*?+量词作用
- 记忆包含的文本
非捕获型括号
反向引用
- 用括号括起来的内容可以被记忆,可以使用序列12来匹配前面括号匹配中的文本,数字取决于是第几个括号
- 分组命名(?<name>exp)
环视功能
环视功能不匹配任何字符,只匹配文本中的特定位置,这一点与单词分界符「b」、锚点「^」和「$」相似。但是,环视比它们更加通用。
环视不会占用字符
-
环视类型
- 顺序环视(?=...),从左至右匹配位置.该位置右边是...
- 逆序环视(?<=...),从右向左匹配位置.该位置左边是...
实例:(?=Jeffrey)Jeff可以匹配by Thomas Jeffery,不可以匹配Jefferson,因为(?=Jeffery)无法找到位置.
-
(?<=Jeff)(?=s)匹配Jeff(位置)s 顺序环视和逆序环视前后顺序是无关紧要的
肯定顺序环视 |
(?=...) |
子表达式可以匹配右侧文本 |
肯定逆序环视 |
(?<=...) |
子表达式可以匹配左侧文本 |
否定顺序环视 |
(?!...) |
子表达式不可以匹配右侧文本 |
否定逆序环视 |
(?<!...) |
子表达式不可以匹配左侧文本 |
元字符优先级
|
转义符 |
(),(?:),(?=),[] |
圆括号和方括号 |
*,+,?,{n},{n,},m} |
限定符 |
^,$,任何元字符、任何字符 |
定位点和序列(即:位置和顺序) |
| |
替换,"或"操作 字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。 |
平衡组//递归匹配
- (?‘group‘)把捕获的内容命名为group并且压入堆栈.
- (?‘-group‘)从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则匹配失败.
- (?(group)yes|no)如果堆栈上存在以group为名的捕获内容,继续匹配yes的内容,反之匹配no的内容.
- (?!)零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败.
经验之谈
- .*会一直匹配到一行的结束,如果不需要匹配反斜线,可以将每个点号替换为"[^n]"
- 处理各种极端情况会降低成本/收益的比例,合适的做法就是不依赖于正则表达式,可以用括号将每个字段括起来,把数字变成程序中的$1,$2,$3,然后进行检验.
- 多选结构应将可能匹配次数多的子表达式放到前面,以减少回溯.
- 加号和星号不要作用于一个元素,会产生大量回溯.
效率
- 消除不必要的括号和字符组
- 不确定的字符用量词优化,确定的字符不要用两次优化.ddd<d{3};111>1{3}.
- 使用非捕获型括号时,字符串结束/行锚点优化会被关闭.(000|999)$>(?:000|999).
- 使用非捕获型括号不但能够提高速度,而且会减少回溯使用的状态的数量.
- 使用锚点^或$,最好将锚点提取出来
- 从量词中提取必须的元素,xx*代替x+,或者用----{0,2}代替-{4,6}.
- 减少匹配长度
实例
- IP--------------------------------b(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])b
- .*单个字符匹配任意次,贪婪匹配.
- .*?满足情况的最小匹配,懒惰匹配.
- 匹配HTML的tag---------------------------------<("[^"]*"|‘[^‘]*‘|[^‘">])*>即<"文本">或<‘文本‘>或<文本>
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|