微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

正则表达式:正向、反向预查

对正则表达式总是望而生畏,现趁有空,补补这块的知识,记录一下正向预查与反向预查:


1.正向预查

现在,我们假设需要仅匹配 Windows,不匹配后面的版本号,并且要求 Windows 后面的版本号只能是 数字类型,换言之,XP 和 Vista 不能被匹配,
在正则表达式中,可以使用 正向预查 来解决这个问题。本例中,写法是:“Windows(?= [\d.]+\b)”。
它的语法是在 子模式内部 前面加“?=”,表示的意思是:首先,要匹配的文本必须满足此子模式前面的表达式(本例,“Windows ”);其次,此子模式不参与匹配。

Text:
Windows 1.03 and Windows 2.0 fisrt Released in 1985 and 1987 respectively.
Windows 95 and Windows 98 are the successor.
Then Windows 2000 and Windows Xp appeared.
Windows Vista is the Latest version of the family.

RegEx:
Windows( ?=[\d.]+\b)


Result:(带下划线的为成功匹配的)
Windows1.03 andWindows2.0 fisrt Released in 1985 and 1987 respectively.
Windows95 andWindows98 are the successor.
ThenWindows2000 and Windows Xp appeared.
Windows Vista is the Latest version of the family.

PHP代码如下:

<?PHP


$reg="#Windows(?=[\d.]+\b)#";
$str="Windows1.03andWindows2.0fisrtReleasedin1985and1987respectively.
Windows95andWindows98arethesuccessor.
ThenWindows2000andWindowsXpappeared.
WindowsVistaistheLatestversionofthefamily.";


if(preg_match_all($reg,$str,$match)){
//code...
var_dump($match);
}else{
//code...
echo("errorcode");
}

结果:
array(1){
[0]=>
array(5){
[0]=>
string(8)"Windows"
[1]=>
string(8)"Windows"
[2]=>
string(8)"Windows"
[3]=>
string(8)"Windows"
[4]=>
string(8)"Windows"
}
}


可以将 正向预查 理解成为自定义的边界(\b),这个边界位于表达式末。
反言之,你可以将位于表达式末的 \b 理解成非获取匹配的一个特例:(?=[,.\r\n<>;\-])。注意,这里没有写全边界符号。
aaaax-aaa

aaaaxaaaa


x(?=[,.\r\n<>;\-])


Result:
aaaax-aaa
aaaaxaaaa

你也可以这样理解上面的匹配过程:
1. 先进行普通匹配:Windows ([\d.]+\b)
2. 然后从匹配文本中将 子模式 内的文本排除掉。


2.反向预查

在上面的例子中,我们知道 正向预查 类似于自定义的 位于文本末 的字符边界。那么自然应该有位于文本首的情况,比如说,我们要匹配下面文本中属于 CNY 的金额:

Text:
CNY: 128.04
USD: 22.5
USD: 23.5
HKD: 1533.5
CNY: 23.78

RegEx:
CNY: \d+\.\d+

Result:
CNY: 128.04

USD: 22.5

USD: 23.5

HKD: 1533.5

CNY: 23.78

与上面类似,我们现在要求仅匹配金额,而不匹配前面的 “CNY:”
正则表达式中,可以使用 反向预查 来解决这个问题。本例中,写法是:(?<=CNY: )\d+\.\d+
反向预查 的语法是在子模式内部前面加“?<=”,表示的意思是:首先,要匹配的文本必须满足此子模式 后面 的表达式(本例,“\d+.\d+”);其次,此子模式不参与匹配。

<?PHP


$reg="#(?<=CNY:)\d+\.\d+#";
$str="CNY:128.04
USD:22.5
USD:23.5
HKD:1533.5
CNY:23.78";


if(preg_match_all($reg,$match)){
//code...
var_dump($match);
}else{
//code...
echo("errorcode");
}

结果:
array(1){
[0]=>
array(2){
[0]=>
string(6)"128.04"
[1]=>
string(5)"23.78"
}
}


与前面类似:你可以将 反向预查 理解成为自定义的边界(\b),这个边界位于 表达式首。
反言之,你可以将位于 表达式首 的 \b 理解成一个获取匹配的一个特例:(?<=[,.\r\n<>;\-])。注意,我没有写全所有边界。
Text:
aaa-xaaaa
aaaxaaaaa
RegEx:
(?<=[,.\r\n<>;\-])x
Result:
aaa-xaaaaaaaxaaaaa
你也可以这样理解上面的匹配过程:1. 先进行普通匹配:(CNY: )\d+\.\d+2. 然后从匹配文本中将 子模式 内的文本排除掉。

原文地址:https://www.jb51.cc/regex/358763.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐