au3 正则参考 -64-负预测先行断言
<!DOCTYPE html>
负预测先行断言: (?!断言模式)
断言模式为有效正则表达式模式. 若要成功匹配, 则输入字符串必须不匹配断言模式的匹配项, 尽管断言模式的匹配项不会包含到最终匹配结果中.
预测先行断言匹配时向右搜索断言模式.
负预测先行断言通常用在正则表达式的开头或结尾:
定义在正则表达式的开头, 表示不能在匹配项的开头处出现断言模式指定的字符串.
定义在正则表达式的末尾, 表示不能在匹配项的末尾处出现断言模式的指定字符串.
负预测先行功能只在断言模式匹配失败的情况下表达式才能成功匹配. 这对于删改一个搜索特别有用, 因为提供应被排除的断言模式通常比提供必须被包括在内的表达式要简单一些.
例如, 编写搜索不以 non 起始的单词的表达式就很困难. 下面的示例使用负预测先行来排除它们.
字符串: Nonsense is not always non-functional.
表达式: \b(?!non)\w+\b
匹配结果(标志 3):
[0]Nonsense Non 不匹配断言模式的 non
[1]is
[2]not
[3]always
[4]functional
表达式分析:
模式 | 说明 |
---|---|
\b | 在单词边界处开始匹配. |
(?!non) | 查看前一个字符以确保当前字符串不以 non 开始. 如果当前字符串以 non 开始, 则匹配失败. |
\w+ | 匹配一个或多个单词字符. |
\b | 在单词边界处结束匹配. |
下面示例在正则表达式开头使用负预测先行断言定义, 以匹配不以字符串 un 开头的单词.
字符串: unite one unethical ethics use untie ultimate
表达式: \b(?!un)\w+\b
匹配结果(标志 3):
[0]one
[1]ethics
[2]use
[3]ultimate
表达式分析:
模式 | 说明 |
---|---|
\b | 在单词边界处开始匹配. |
(?!un) | 负预测先行断言. 确定 \b 后接下来的两个字符是否为 un , 如果不是则可以匹配. 如果 (?!un) 匹配成功 , 则匹配结果及其后的 1 或多个单词字符排除在最终匹配结果之外 ; 如果 (?!un) 匹配失败 , 则捕获的 1 或多个单词字符串包含到最终结果中 . |
\w+ | 匹配一个或多个单词字符. |
\b | 在单词边界处结束匹配. |
下面的示例在正则表达式的末尾使用负预测先行断言定义, 以匹配不以标点字符结束的单词:
字符串: Disconnected, disjointed thoughts in a sentence fragment.
表达式: \b\w+\b(?!\p{P})
匹配结果(标志 3):
[0]disjointed
[1]thoughts
[2]in
[3]a
[4]sentence
表达式分析:
模式 | 说明 |
---|---|
\b | 在单词边界处开始匹配 |
\w+ | 匹配一个或多个单词字符. |
\b | 在单词边界处结束匹配. |
(?!\p{P}) | 负预测先行断言. 如果下个字符不是一个标点符号(如句点或逗号)则匹配成功. 检查 \b\w+\b 匹配项的左侧 ( 前面 , 负预测 , )是否有 \p{P} 匹配的标点符号 : 如果 (?!\p{P}) 匹配成功 , 则最终匹配结果排除 \b\w+\b 的匹配项 ; 如果 (?!\p{P}) 匹配失败 , 则最终匹配结果包含 \b\w+\b 的匹配项 . |
负预测先行断言匹配过程:
字符串: aa
one
bb表达式: <(?!/?p\b)[^>]+>
匹配结果(标志 3) : [0]
这个正则的意义就是匹配除
或
之外的其余标签.首先由字符 < 取得控制权, 从位置 0 开始匹配, 由于 < 匹配 " a " 失败, 在位置 0 处整个表达式匹配失败, 第一次迭代匹配失败, 正则引擎向前传动, 由位置 1 处开始尝试第二次迭代匹配. 重复前面过程, 直到位置 2, < 匹配成功, 控制权交给 (?!/?p\b) ;
断言模式 (?!/?p\b) 取得控制权后, 进行断言模式内部的匹配. 首先由 /?( 0 个或 1 个反斜杠 ) 取得控制权, 尝试匹配字符 p 失败, 进行不匹配回溯, 控制权交给 p 尝试匹配 p , 匹配成功, 控制权交给 \b 尝试匹配位置 4, 匹配成功. 此时断言模式 /?p\b 匹配成功, 那么负预测先行断言 (?!/?p\b) 就匹配失败. 在位置 2 处整个表达式匹配失败, 新一轮迭代匹配失败, 正则引擎向前传动, 由位置 3 处开始尝试下一轮迭代匹配.
在位置 8 处也会遇到一轮 /?p\b 匹配 /p 成功, 而导致负预测先行断言 (?!/?p\b) 匹配失败, 从而导致整个表达式匹配失败.
重复以上过程, 直到位置 14, < 匹配成功, 控制权交给 (?!/?p\b) ; /? 尝试匹配反斜杠 / 失败, 进行不匹配回溯, 控制权交给 p 尝试匹配 , 匹配失败, 已经没有备选状态可供回溯, 匹配失败. 此时断言模式匹配完成, /?p\b 匹配失败, 那么负预测先行断言 (?!/?p\b) 匹配成功. 匹配的结果是位置 15, 然后控制权交给 [^>]+ ; 由 [^>]+ 从位置 15 进行尝试匹配, 可以成功匹配到 div , 控制权交给 > 来匹配 > .
此时正则表达式匹配完成, 报告匹配成功. 匹配结果为
发表评论
木有头像就木JJ啦!还木有头像吗?点这里申请属于你的个性Gravatar头像吧!