正则表达式匹配号后不带连字符

时间:2018-07-10 11:48:02

标签: php regex

我使用正则表达式已经有很多年了,编写正则表达式从来没有这么麻烦。我正在使用PHP 7.2.2的preg_match()返回匹配数字的数组以进行解析,因此将正则表达式中的括号删除。

我试图匹配一个或多个数字,后跟一个“ x”,再匹配一个或多个数字,其中整个字符串后不带连字符。当$ input为“ 18x18”或“ 18x18-”时,匹配为18和1。当$ input为“ 8x8”时,没有匹配。我似乎在这里做一些根本错误的事情。

<?php
$input = "18x18";    
preg_match("/(\d+)x(\d+)[^-]/", $input, $matches);

调用print_r($ matches)会导致:

Array
(
    [0] => 18x18
    [1] => 18
    [2] => 1
)

这里有括号,因为我正在使用PHP的preg_match返回匹配项数组。我了解何时应避免使用连字符,并且我尝试了两种方法来确定但得到相同的结果。为什么这个不匹配?

1 个答案:

答案 0 :(得分:2)

您可以使用

'~(\d+)x(\d++)(?!-)~'

由于前瞻内部的\d也将禁止部分匹配第二位数字,因此它也可以不带有所有格修饰符而写为'~(\d+)x(\d+)(?![-\d])~',因为

或者,除了前行之外,您还可以使用单词边界:

'~\b(\d+)x(\d+)\b(?!-)~'

请参见regex demo #1regex demo #2

详细信息

  • (\d+)x(\d++)(?!-) / (\d+)x(\d+)(?![-\d])-匹配并将1个或多个数字捕获到组1中,然后匹配x,然后匹配并将一个或多个数字捕获到组2中 ,而不会回溯到数字匹配模式中,并且一次执行(?!-)否定超前检查(确保在当前位置之后没有-一次 \d++之后匹配所有可以匹配的数字。在\d+(?![-\d])的情况下,先匹配1+个数字,然后负向查找确保当前位置右边没有数字 -
  • \b(\d+)x(\d+)\b(?!-)-首先匹配单词边界,然后将1个或多个数字匹配并捕获到组1中,然后匹配x,然后将一个或多个数字匹配并捕获到组2中,然后断言有一个单词边界,只有这样才能确保之后没有-

查看PHP demo

if (preg_match('~(\d+)x(\d++)(?!-)~', "18x18", $m)) {
    echo "18x18: " . $m[1] . " - " . $m[2] . "\n";
}
if (preg_match('~\b(\d+)x(\d+)\b(?!-)~', "18x18", $m)) {
    echo "18x18: " . $m[1] . " - " . $m[2] . "\n";
}
if (preg_match('~(\d+)x(\d++)(?!-)~', "18x18-", $m)) {
    echo "18x18-: " . $m[1] . " - " . $m[2] . "\n";
}
if (preg_match('~\b(\d+)x(\d+)\b(?!-)~', "18x18-", $m)) {
    echo "18x18-: " . $m[1] . " - " . $m[2];
}

输出:

18x18: 18 - 18
18x18: 18 - 18