问题
I tried the solution for phone numbers with 7-12 digits that may contain spaces or hypens in the following link. The first and last character has to be a number.
Regular expression to match 7-12 digits; may contain space or hyphen
However, i'm not understanding the regex well.
$phone_pattern="/^\d(?:[-\s]?\d){6,11}$/";
what does the ":" mean here?
How is this regex able to exclude the hypens and spaces from the 6 to 11 characters?
Help help is highly appreciated
回答1:
Have you tried a testing engine like regexpal (there are others available also) I frequently use this to test various strings against expressions to make sure they are behaving as expected.
My understanding is that in this case the : is not acting alone it is acting in conjunction with the ?
The ? in this circumstance does not mean Preceding zero or one times it is a modifier meaning give this group a new meaning which in conjunction with the modifier : turn off capture means you want this to be a non capturing group expression.
The effect that this has is that when placing part of an expression inside () it by default causes capture but ?: switches this off.
Thus (?:[-\s]?\d) becomes a non capturing group expression.
Note captured groups are used with back references and most regex engines support up to 9 back references.
So removing capture speeds up the matching process and allows you to elect not to refer back to that group saving one of your 9 references for a group that you really do want to refer back to.
回答2:
The :
is part of the (?: ... )
- which means "non-capturing group" - it groups content but does not create a backreference to it (i.e. $1, $2, etc) like normal grouping does.
In that regex it will match from 6 up to 11 characters, including the heiphens and spaces - it meaning something like 12-------34 would match. I suggest using a more strict pattern:
/^\d{7,12}$/
This will only match the digits. To allow for heiphens and spaces with this match, but only get the number you want, you can use it like this:
<?php
$pattern = '/^\d{7,12}$/';
$string = '123-456 789';
$ignoreCharacters = array(' ', '-');
preg_match($pattern, str_replace($ignoreCharacters, $string);
回答3:
It's understandable how that can be confusing. The (?: ... )
actually denotes a "non-capturing group," as opposed to the ( ... )
, which is a "capturing group". If you're only testing strings against regexes, not capturing substrings, then the two are effectively the same for your purposes.
It doesn't help that there also exist (?= ... )
, (?! ... )
, (?<= ... )
, (?<! ... )
, and (?<foo> ... )
, which all mean different things, too.
A lot to learn, but rewarding for sure!
来源:https://stackoverflow.com/questions/12704345/php-regex-phone-number-7-12-digits-may-contain-hypen-or-space