Search code examples
phpregexpreg-match

regex exclude dash/hyphen if there no number found afterward


I'm tried to extract number between a hyphen, it works but when the number after hyphen is not found and leaving with whitespace it will take the hyphen into the match.

Here the code what I tried with:

$join = '';
if (preg_match('/(?<=book)[\s\d]+-?[\s\d]+/i', $find, $matches)) {
    if (strpos($matches[0], ' ') && strpos($matches[0], '-')) {
        $remove_whitespace = str_replace(' ', '', $matches[0]);
        $join.= 'b' . $remove_whitespace;
    }
    else {
        $remove_whitespace = str_replace(' ', '', $matches[0]);
        $join.= 'b' . $remove_whitespace;
    }
    echo $join;
}

What I expected:

  1. "Book 1 - abcd" = "Book 1"
  2. "Book 1 - " = "Book 1"
  3. "Book 1 - 2" = "Book 1-2"

The actual output:

  1. "Book 1 - abcd" = "Book 1-" (had hyphen with it)
  2. "Book 1 - " = "Book 1-" (had hyphen with it)
  3. "Book 1 - 2" = "Book 1-2"

Solution

  • You may use

    '~Book\s*\K\d+(?:\s*-\s*\d+)?~'
    

    See the regex demo

    Details

    • Book - a literal string
    • \s* - 0+ whitespaces
    • \K - match reset operator that discards the text matched so far
    • \d+ - 1+ digits
    • (?:\s*-\s*\d+)? - an optional sequence of a - enclosed with 0+ whitespaces (\s*-\s*) and then 1+ digits.