开发者

Filter array of numeric PIN code strings which may be in the format "######" or "### ###"

I have a PHP array of strings. The strings are supposed to represent PIN codes which are of 6 digits lik开发者_StackOverflow中文版e:

560095

Having a space after the first 3 digits is also considered valid e.g. 560 095.

Not all array elements are valid. I want to filter out all invalid PIN codes.


Yes you can make use of regex for this.

PHP has a function called preg_grep to which you pass your regular expression and it returns a new array with entries from the input array that match the pattern.

$new_array = preg_grep('/^\d{3} ?\d{3}$/',$array);

Explanation of the regex:

^     - Start anchor
\d{3} - 3 digits. Same as [0-9][0-9][0-9]
 ?    - optional space (there is a space before ?)
        If you want to allow any number of any whitespace between the groups
        you can use \s* instead
\d{3} - 3 digits
$     - End anchor


Yes, you can use a regular expression to make sure there are 6 digits with or without a space.

A neat tool for playing with regular expressions is RegExr... here's what RegEx I came up with:

^[0-9]{3}\s?[0-9]{3}$

It matches the beginning of the string ^, then any three numbers [0-9]{3} followed by an optional space \s? followed by another three numbers [0-9]{3}, followed by the end of the string $.

Passing the array into the PHP function preg_grep along with the Regex will return a new array with only matching indeces.


If you just want to iterate over the valid responses (loop over them), you could always use a RegexIterator:

$regex = '/^\d{3}\s?\d{3}$/';
$it = new RegexIterator(new ArrayIterator($array), $regex);
foreach ($it as $valid) {
    //Only matching items will be looped over, non-matching will be skipped
}

It has the benefit of not copying the entire array (it computes the next one when you want it). So it's much more memory efficient than doing something with preg_grep for large arrays. But it also will be slower if you iterate multiple times (but for a single iteration it should be faster due to the memory usage).


If you want to get an array of the valid PIN codes, use codaddict's answer.

You could also, at the same time as filtering only valid PINs, remove the optional space character so that all PINs become 6 digits by using preg_filter:

$new_array = preg_filter('/^(\d{3}) ?(\d{3})$/D', '$1$2', $array);


The best answer might depend on your situation, but if you wanted to do a simple and low cost check first...

$item = str_replace( " ", "", $var );

if ( strlen( $item ) !== 6 ){
echo 'fail early';
}

Following that, you could equally go on and do some type checking - as long as valid numbers did not start with a 0 in which case is might be more difficult.

If you don't fail early, then go on with the regex solutions already posted.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜