正则表达式匹配号码后面没有连字符 [英] Regex match numbers not followed by a hyphen

查看:42
本文介绍了正则表达式匹配号码后面没有连字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've worked with regexes for years and never had this much trouble working out a regex. I am using PHP 7.2.2's preg_match() to return an array of matching numbers for parsing, hence the parentheses in the regex.

我试图匹配一个或多个数字后跟一个 x 后跟一个或多个数字,其中整个字符串后面没有连字符.当 $input 为 18x1818x18-18x18size 时,匹配的是 181.当 $input8x8 时,没有匹配项.

I am trying to match one or more numbers followed by an x followed by one or more numbers where the entire string is not followed by a hyphen. When $input is 18x18, 18x18- or 18x18size, the matches are 18 and 1. When the $input is 8x8, there are no matches.

我似乎在这里做错了什么.

I seem to be doing something fundamentally wrong here.

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

调用 print_r($matches) 结果:

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

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

The parens are there because I am using PHP's preg_match to return an array of matches. I understand when hyphens should be escaped and I've tried both ways to be sure but get the same results. Why doesn't this match?

推荐答案

您可以使用

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

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

It can also be written without a possessive quantifier as '~(\d+)x(\d+)(?![-\d])~' since the \d inside the lookahead will also forbid matching the second digit chunk partially.

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

Alternatively, additionally to the lookahead, you may use word boundaries:

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

请参阅正则表达式演示 #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 一个或多个数字,然后断言有一个词边界,然后才确定后面没有-.立>
  • (\d+)x(\d++)(?!-) / (\d+)x(\d+)(?![-\d]) - matches and captures 1 or more digits into Group 1, then matches x, and then matches and captures into Group 2 one or more digits possessively without letting backtracking into the digit matching pattern, and the (?!-) negative lookahead check (making sure there is no - immediately after the current position) is performed once after \d++ matches all the digits it can. In case of \d+(?![-\d]), the 1+ digits are matched first, and then the negative lookahead makes sure there is no digit and - immediately to the right of the current location.
  • \b(\d+)x(\d+)\b(?!-) - matches a word boundary first, then matches and captures 1 or more digits into Group 1, then matches x, then matches and captures into Group 2 one or more digits, then asserts that there is a word boundary, and only then makes sure there is no - right after.

查看 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];
}

输出:

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

这篇关于正则表达式匹配号码后面没有连字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆