假设我有以下行:
1309270927C1642,61N654NONREF
现在我想得到第一个数字之后的C
或D
。现在这里有一些规则
- 前6位数字始终存在
- 之后的4位数字是可选的
- 之后,您将获得
D
或C
现在我想看看背后的问题:
/(?<='d{6,10})D|C/
,但这在PHP中是不允许的。
所以我尝试了一个非捕获组/(?:'d{6,10})D|C/
。但这捕获了1309270927C
而不仅仅是C
。
所以我的问题是,我如何才能只捕获D
或C
?
我会使用捕获子模式,如下所示:
$string = "1309270927C1642,61N654NONREF";
$pattern = '/'d{6,10}(C|D)/';
preg_match($pattern, $string, $matches);
// $matches[1] contains the contents of the first subpattern
echo $matches[1];
您可以使用PCRE 'K
运算符:
'd{6,10}'K[DC]
它将省略匹配中直到D
或C
的所有内容。您可以进一步调整此正则表达式,允许或不允许字符类[DC]
包含更多字符。
看看这个例子。
样本代码:
$re = "/''d{6,10}''K[DC]/";
$str = "1309270927C1642,61N654NONREF";
preg_match_all($re, $str, $matches);
此外,这里还有一些关于'K
操作员的更多信息:
The 'K "keep out" verb, which is available in Perl, PCRE (C, PHP, R…)
and Ruby 2+. 'K tells the engine to drop whatever it has matched so
far from the match to be returned.
Instead of (?<='b'd+_)[A-Z]+, you can therefore use 'b'd+_'K[A-Z]+
'K
:的局限性
与lookbehinds相比,''K和捕获组的解决方案都有局限性:
✽当您在字符串中查找多个匹配项时每次比赛尝试的位置,后方人员可以检查字符串中当前位置后面的字符。因此对于123,模式(?<=''d)''d(匹配前面的数字)将匹配2和3。相反,''d''K''d只能匹配2,因为第一场比赛之后的起始位置紧接在3,并且没有足够的数字用于第二次匹配。同样地''d(''d)只能捕获2。
✽使用lookbehinds,您可以施加多种条件(类似于我们的密码验证技术)。对于例如,匹配前面有小写希腊文的数字字母,您可以使用(?<=''p{Ll})(?&llt;=''p{Greek})''d。第一次观察(?<=''p{Ll})确保紧邻左边的字符是小写字母,第二个lookbacking(?<=''p{Greek})确保左边的字符属于希腊语剧本有了解决方法,您可以使用''p{Greek}''K''d来匹配前面有希腊文字字符的数字(或''p{Greek}(''d)到捕获它),但不能强加第二个条件。克服这个限制,您可以捕获希腊字符并使用第二个regex来检查它是否是小写字母。
输出:
C