Hi all,
I'd like to filter an input string with a list of commas separated numeric ids to understand if it matches the pattern (only digits and commas allowed, i.e. "112,5,16,4578,ecc").

I'm trying to perform a regular expression match using preg_match.

$ids_list = '112,5,16,4578';

if (preg_match('/[0-9,]*/', $ids_list))
  echo'OK!';
else
  echo'KO!';

Well, it doesn't work at all, printing nearly always an OK! output, even if I put in a ";aaaa;bbbb;" string which is totally alien from the given pattern, what's wrong with it?
Tnx

Recommended Answers

All 5 Replies

Try this

if (preg_match('/[^0-9,]/', $ids_list)) {
  echo 'No good!';
} else {
  echo 'OK!'; //only 0 to 9 and commas.
}

Your regex pattern has two problems:
1. it has * as the character counter, which means "0 or any number of charcaters frm the class".
This means that a string containing even none (0) of your characters will match your expression
2. you didn't specify that there cannot be other characters before and after the pattern
Here is how it should be:

$ids_list = '112,5,16,4578';
 
if (preg_match('/^[0-9,]+$/', $ids_list))
  echo'OK!';
else
  echo'KO!';

The "+" sign after the character class says there should be at least 1 character from there
The ^ at the beginning and $ at the end say you cannot have other characters before and after the string matching your pattern.
However, this solution will also match "," - a single comma string.
Maybe a better one would be

$ids_list = '112,5,16,4578';
 
if (preg_match('/^[0-9]+(,[0-9]+)*$/', $ids_list))
  echo'OK!';
else
  echo'KO!';

This matches a string containing a group of 1 or more digits, followed by 0 or more groups of a comma followed by some digits
;)

That's perfect, I've tested it with my test cases and it works under all conditions.

Now, I'd like to perform a more complex recognition, given a string, I must tell if it's the kind of one of these patterns:

01.* (a two digit number followed by '.*')
01.0123.* (a two digit number followed by a point, a four digit number and '.*')
01.0123.01 (a two digit number followed by a point, a four digit number, a point and a two digit number)

I tried

if (preg_match('/^[0-9]{2}[.]{1}[*]{1}$/', $article)) {
            // first pattern
        }
        if (preg_match('/^[0-9]{2}[.]{1}[0-9]{4}[.]{1}[*]{1}$/', $article)) {
            // second pattern
        }
        if (preg_match('/^[0-9]{2}[.]{1}[0-9]{4}[.]{1}[0-9]{2}$/', $article)) {
            // third pattern
        }

is it correct? Surely it can be shortened...

You can test for all the three patterns at once with this

if (preg_match('/^([0-9]{2}\.\*|[0-9]{2}\.[0-9]{4}\.\*|[0-9]{2}\.[0-9]{4}\.[0-9]{2})$/', $article)) {
   // match
}
else {
   // no match
}

The '.' (dot) and the "*" are special characters in regular expressions, so if you want to match those characters you have to escape them (put a "\" - backslash - before each special character you want to escape)

I've to escape them with a backslash only if I put them alone (as you did), it's not required if I put them within square brackets instead, isn't it?
If I want to match a comma separated list with those expressions, is this a correct way?

if (preg_match('/^([0-9]{2}\.\*|[0-9]{2}\.[0-9]{4}\.\*|[0-9]{2}\.[0-9]{4}\.[0-9]{2})(,([0-9]{2}\.\*|[0-9]{2}\.[0-9]{4}\.\*|[0-9]{2}\.[0-9]{4}\.[0-9]{2}))*$/', $article_list)) {
   // match
}
else {
  // no match
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.