Regular/Lookaround

来自康健生活
跳转到导航 跳转到搜索

Lookaround (预搜索、断言、环视)

如同^代表开头,$代表结尾,\b代表单词边界一样,先行断言和后行断言也有类似的作用,它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为“零宽”。所谓位置,是指字符串中(每行)第一个字符的左边、最后一个字符的右边以及相邻字符的中间(假设文字方向是头左尾右)。

环视只进行子表达式的匹配,不占有字符,匹配到的内容不保存到最终的匹配结果,是零宽度的。环视匹配的最终结果就是一个位置。

环视的作用相当于对所在位置加了一个附加条件,只有满足这个条件,环视子表达式才能匹配成功。

环视按照方向划分有顺序和逆序两种,按照是否匹配有肯定和否定两种,组合起来就有四种环视。顺序环视相当于在当前位置右侧附加一个条件,而逆序环视相当于在当前位置左侧附加一个条件。

正向(positive) 匹配括号中的表达式
负向(negative) 不匹配括号中的表达式

Lookahead (先行断言)

引擎会尝试匹配指针还未扫过的字符,先于指针到达该字符,故称为先行。

表达式 标题 描述 解析
(?=Expression)

顺序肯定环视、
零宽度正预测先行断言、
零宽正向先行断言、
zero-width positive lookahead assertion

表示所在位置右侧的字符序列能够匹配Expression Expression匹配成功时,(?=Expression)匹配成功,并报告(?=Expression)匹配当前位置成功
(?!Expression)

顺序否定环视、
零宽度负预测先行断言、
零宽负向先行断言、
zero-width negative lookahead assertion

表示所在位置右侧的字符序列不能匹配Expression Expression匹配成功时,(?!Expression)匹配失败;

Expression匹配失败时,(?!Expression)匹配成功,并报告(?!Expression)匹配当前位置成功

(?=Expression)
描述 文本 正则 结果
匹配live中的li life live living inline
li(?=ve)
li
li(?=ve)..
live
匹配以ing结尾的单词 I'm singing while you're dancing
\b\w+(?=ing\b)...
singing

dancing

(?!Expression)
描述 文本 正则 结果
匹配除live外的li life live living inline
li(?!ve)
li
li(?!ve)..
life

livi

line

匹配三位数字且三位数字后面不能是数字
\d{3}(?!\d)
匹配不包含连续字符串abc的单词
\b((?!abc)\w)+\b
匹配除<p…>或</p>之外的其余标签 aa<p>one</p>bb<div>two</div>cc
<(?!/?p\b)[^>]+>
<div>

</div>

Lookbehind (后行断言)

引擎会尝试匹配指针已扫过的字符,后于指针到达该字符,故称为后行。

表达式 标题 描述 解析
(?<=Expression)

逆序肯定环视、
零宽度正回顾后发断言、
零宽正向后行断言、
zero-width positive lookbehind assertion

表示所在位置左侧的字符序列能够匹配Expression Expression匹配成功时,(?<=Expression)匹配成功,并报告(?<=Expression)匹配当前位置
(?<!Expression)

逆序否定环视、
零宽度负回顾后发断言、
零宽负向后行断言、
zero-width negative lookbehind assertion

表示所在位置左侧的字符序列不能匹配Expression Expression匹配成功时,(?<!Expression)匹配失败;

Expression匹配失败时,(?<!Expression)匹配成功,并报告(?<!Expression)匹配当前位置

(?<=Expression)
描述 文本 正则 结果
匹配inline中的li life live living inline
(?<=\w)li
li
(?<=\w)li..
line
匹配以re开头的单词的后半部分 reading a book
(?<=\bre)\w+\b
ading
匹配<div>和</div>标签之间的内容且不包括<div>和</div>标签本身 <div>a test</div>
(?<=<div>)[^<]+(?=</div>)
a test
(?<!Expression)
描述 文本 正则 结果
匹配以li 开始且li不在内部 life live living inline
(?<!\w)li
li
(?<!\w)li..
life

live

livi

匹配前面不是小写字母的七位数字
(?<![a-z])\d{7}

Instance

描述 文本 正则 结果
段落包含this this is the case.

note that this is the case.

^((?<!that).)*this((?<!that).)*
this is the case.
^(.(?!that))*this(.(?!that))*
^((?!that).)*this(.(?<!that))*
^((?!that).)*this((?!that).)*
匹配包含后面不是字母u的字母q的单词 Iraq,Benq.

Iraq fighting.

\b\w*q[^u]\w*\b
[^u]
匹配一个字符
\w*\b
匹配下一个单词
匹配不包含属性的简单HTML标签内里的内容
(?<=<(\w+)>).*(?=<\/\1>)
(?<=<(\w+)>).
指定前缀
\1
反向引用
匹配以空白符间隔的数字不包括空白符
(?<=\s)\d+(?=\s)