正则表达式匹配号码后面没有连字符

Tod*_*mer 0 php regex

我使用正则表达式已经很多年了,在计算正则表达式时从来没有遇到过这么多麻烦。我正在使用 PHP 7.2.2preg_match()返回一组匹配数字进行解析,因此使用正则表达式中的括号。

我试图匹配一个或多个数字,x后跟一个或多个数字,其中整个字符串后面没有连字符。当 $input 是18x18, 18x18-or 时18x18size,匹配的是18and 1。当$inputis 时8x8,没有匹配项。

我在这里似乎在做一些根本错误的事情。

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

调用print_r($matches)结果:

Array
(
    [0] => 18x18
    [1] => 18
    [2] => 1
)
Run Code Online (Sandbox Code Playgroud)

括号在那里是因为我使用 PHP 的 preg_match 返回匹配数组。我知道什么时候应该转义连字符,我已经尝试了两种方法来确保但得到相同的结果。为什么这不匹配?

Wik*_*żew 6

您可以使用

'~(\d+)x(\d++)(?!-)~'
Run Code Online (Sandbox Code Playgroud)

它也可以在没有所有格量词的情况下编写,'~(\d+)x(\d+)(?![-\d])~'因为\d前瞻的内部也将禁止部分匹配第二个数字块。

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

'~\b(\d+)x(\d+)\b(?!-)~'
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示 #1正则表达式演示 #2

细节

  • (\d+)x(\d++)(?!-)/ (\d+)x(\d+)(?![-\d])- 将 1 个或多个数字匹配并捕获到 Group 1,然后匹配x,然后将一个或多个数字占有地匹配并捕获到 Group 2 中,而不让回溯到数字匹配模式,以及(?!-)否定前瞻检查(确保没有-立即在当前位置之后)在匹配所有可以匹配的数字后执行一次\d++。在 的情况下\d+(?![-\d]),首先匹配 1+ 数字,然后负前瞻确保没有数字并且 -紧靠当前位置的右侧。
  • \b(\d+)x(\d+)\b(?!-)- 首先匹配一个词边界,然后匹配并捕获 1 个或多个数字到 Group 1,然后匹配x,然后匹配并捕获到 Group 2 一个或多个数字,然后断言有一个词边界,然后才确定有没有-权利之后。

看一个PHP 演示

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];
}
Run Code Online (Sandbox Code Playgroud)

输出:

18x18: 18 - 18
18x18: 18 - 18
Run Code Online (Sandbox Code Playgroud)