Regex match numbers not followed by a hyphen

后端 未结 1 1974
广开言路
广开言路 2021-01-26 20:22

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,

相关标签:
1条回答
  • 2021-01-26 21:05

    You may use

    '~(\d+)x(\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(?!-)~'
    

    See the regex demo #1 and regex demo #2.

    Details

    • (\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.

    See a 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];
    }
    

    Output:

    18x18: 18 - 18
    18x18: 18 - 18
    
    0 讨论(0)
提交回复
热议问题