Reputation: 881
My account creation script's name input is validated with a preg_match
as the field is only allowed to have either Latin or Cyrillic characters (in other words, it cannot have both), however, no matter what the name field contains, the preg_match
condition is never satisfied. So far I've tried three possible variations of the code:
if (!(preg_match('/^[a-z]$/i',$_POST['name']) || preg_match('/^[а-я]$/i',$_POST['name']))) back('The message');
if (!preg_match('/^[a-z]$/i',$_POST['name']) && !preg_match('/^[а-я]$/i',$_POST['name'])) back('The message');
and one that attempts to stuff both the preg matches into one.
Could anyone please help me out in fixing this issue?
Upvotes: 1
Views: 324
Reputation: 3713
With your condition, if the first "if" does not pass, the second won't either because they are equivalent !(A or B) <=> !A && !B
what you want is a xor
Moreover, you just test only one character with your "preg match" here.
your condition should be
if( preg_match('/^[a-z]+$/iu',$_POST['name']) xor preg_match('/^[а-я]+$/iu',$_POST['name']){
// do what you want
}
Upvotes: 0
Reputation: 145482
You could also assert both in one regex:
if (!preg_match('/ ^[a-z]+$ | ^[\p{Cyrillic}]+$ /ixu',$_POST['name'])) {
Note the two |
alternatives, bot constrained by ^
and $
.
There is also \p{Latin}
, not just \p{Cyrillic}
for matching the complete character range.
Upvotes: 1
Reputation: 522155
Let's abstract those preg_match
functions into the names is_latin
and is_cyrillic
for readability. You're then looking for the logic:
if is_latin xor is_cyrillic -> OK
else -> not OK
Or, inverted:
if !(is_latin xor is_cyrillic) -> not OK
xor
is only true if one is true
and the other false
.
Additionally, your regexen match only a single character. You'll want /^[a-z]+$/i
to match a whole word. Further, to match a non-latin word/regex, you need to use the u
modifier like /^[а-я]+$/iu
and make sure your source code and the subject are encoded in UTF-8. So:
if (!(preg_match('/^[a-z]+$/i', $_POST['name']) xor preg_match('/^[а-я]+$/iu', $_POST['name']))) {
// error
}
You can even shorten this into one regex:
if (!preg_match('/^([a-z]+|[а-я]+)$/iu', $_POST['name'])) {
// error
}
Upvotes: 1
Reputation: 91744
The problem is that you are limiting the name to exactly one character:
/^[a-z]$/i
Change it to:
/^[a-z]+$/i
and
/^[а-я]+$/i
Upvotes: 4