Regex for single digit catches two digit numbers?

Viewed 156

This regex catches two digit nubers:

if I have y11 it will still catch it, how to match only y0, y1, y2, y3, y4, y5, y6, y7, y8, y9 ?? After the digit there might be a blank space or a letter or a dot.

preg_replace('/y([1-9]{1})/', 'y0$1', $string)
5 Answers

I would match on the pattern y\d(?!\d), which matches y followed by a single digit, which itself is not followed by another digit.

$string = "y2";
echo $string . "\n";
$string = preg_replace("/y(\d)(?!\d)/", "y0$1", $string);
echo $string;

This prints:

y2
y02

Explanation of regex:

y       the letter 'y'
(\d)    a single digit (capture it)
(?!\d)  assert that what follows is either a non digit character OR
        the end of the input

You can omit {1} and [1-9] does not match a 0. The pattern partially matches for example y1 in y11 as the pattern is unanchored.

You can match a y followed by a digit and assert either a space, dot or letter or the end of the string.

\by\K\d(?=[\h\p{L}.]|$)

The pattern matches

  • \by Match y preceded by a word boundary
  • \K Forget what is matched so far
  • \d Match a single digit 0-9
  • (?= Positive lookahead, assert what is directly to the right is
    • [\h\p{L}.] Match either a horizontal whitespace char, any letter or a dot
    • | Or
    • $ End of string
  • ) Close lookahead

Regex demo | Php demo

In the replacement use the full match preceded by a 0

$pattern = "/\by\K\d(?=[\h\p{L}.]|$)/";
$strings = [
    "y0",
    "y1$",
    "y2H",
    "y3.",
    "y9 ",
    "y10",
    "y09  y3 ay9"
];

foreach ($strings as $s) {
    echo preg_replace($pattern, "0$0", $s) . PHP_EOL;
}

Output

y00
y1$
y02H
y03.
y09 
y10
y09  y03 ay9

With your shown samples, please try following regex.

^[a-zA-Z]\d[\s.a-zA-Z]?$

OR you want to match exactly values starting from y then change above to:

^y\d[\s.a-zA-Z]?$

Online demo for above regex

Explanation: Adding detailed explanation for above.

^                   ##Mentioning ^ caret sign to denote starting of value.
[a-zA-Z]            ##Checking 1 alphabet(small/capital letters) here.
\d                  ##Matching 1 single digit here.
[\s.a-zA-Z]?        ##Checking either space OR DOT or small or capital letter to match, this is keep optional.
$                   ##Mentioning end of the value here.
[a-zA-Z]+(\d)([,\sa-zA-Z.]|\b)
  • [a-zA-Z]+ Match a character or characters.
  • (\d) to match a single digit. Add them in a capturing group to replace later.
  • ([,\sa-zA-Z.]|\b) to match the text immediately followed by this comma, space or word boundary or letters.
  • Make sure to add $2 too to preserve it's initial representation while replacing.

Snippet:

<?php

$str = 'y0, y1, y2, y03, y4, y5, y6, y7, y8, y9, y99, y101';

$str = preg_replace('/[a-zA-Z]+(\d)([,\sa-zA-Z.]|\b)/','y0$1$2',$str);

echo $str;
Related