views:

128

answers:

5

I need a regex that checks if a string only contain letters(a-z) and that the first letter is uppercase, you cant have 2 letters in a word uppercase Like: THomas or THomAS but Thomas Anderson (Thomas anderson too) would be valid

look:

The Magician Of The Elfs would be valid but not ThE MaGiCiAN oF ThE ELFS

if (!preg_match("??", $name)) {
   echo "Invalid name!";
}

hope you understand!

Tomasz

Invalid:

MaGIciaN Of The ELFz
THomas anderson

Valid:

Magician of the elfs
Magician Of the Elfs
Magician of The elfs
Thomas Anderson
Thomas anderson

Basically i dont want it to be possible to have more than 1 capitalized letter in a word, not sentence.

+4  A: 
'/^[A-Z][a-z]+( [A-Z][a-z]+)*$/'

Untested, though.

EDIT Oh, perhaps I misread your question. The above assumes a minimum word length of two. Is "John A" or "A Horse" valid? In that case: '/^[A-Z][a-z]*( [A-Z][a-z]*)*$/'.


According to updated requirements:

'/^[A-Z][a-z]*( [A-Za-z][a-z]*)*$/'

Validates one capitalized letter followed by any number of lowercase letters. After this, any number of the sequence: space, (possibly an uppercase letter), any number of lowercase letters (at least one letter in total for each space).

jensgram
That should do the trick. Note that PHP expects delimiters, which I added.
Bart Kiers
Yup, I forgot (and we had a little edit collision). Should be OK now.
jensgram
wait, i would like John horse to be valid too
Tomasz
+1  A: 
$str = "ThE MaGiCiAN oF ThE ELFS";
$s = explode(" ",$str);
foreach ($s as $k){
    if ( ! (preg_match("/^[A-Z][a-z]+/",$k) )){
        print "$str does not match.\n";
        break;
    }
}
ghostdog74
+1 for simplicity
Ahmad Dwaik
+3  A: 

You can also describe the character by its Unicode character properties:

/^\p{Lu}\p{Ll}*(?:\s+\p{Lu}\p{Ll}*)*$/

Edit    Since you changed your requirements, try this regular expression:

/^[\p{Lu}\p{Ll}]\p{Ll}*(?:\s+[\p{Lu}\p{Ll}]\p{Ll}*)*$/

Now the first character or each word can be an uppercase letter or a lowercase letter.

Gumbo
A: 

Wow. \b, guys.

if matches /\B[A-Z]/ then invalid

or, to be Unicode aware,

if matches /\B\p{Lu}/ then invalid

You may want to ensure the whole string matches /^[\p{Lu}\p{Ll}\s]$/ first, to avoid leaving strings like The (Magic) Elf as valid.

KennyTM
So you're proposing to do it in two steps? In that case, I prefer Gumbo and jensgram's solutions (just one fairly intuitive step). If you don't perform the second validation, not just `The (Magic) Elf` would pass, but also strings like `????????` or `11111111122222222` etc.
Bart Kiers
That depends on whether the input already is already filtered, because the asker's example doesn't include these cases. (And updated to further simplify the test.)
KennyTM
In fact, `????????` and `1111111122222222` satisfies the basic requirement "(not) to have more than 1 capitalized letter in a word". There is no words nor capitalized letters in the string, so it passes.
KennyTM
Nothing in the "valid examples" suggests these are valid, but sure: they could be. I wouldn't put money on it though! :)
Bart Kiers
Haha, that's why a precise specification is costly :p
KennyTM
A: 
if (preg_match("\w[A-Z]", $name)) {
 echo "invalid name!";
}
h-markus
No, that will positively validate `????????` or `11111111122222222` etc.
Bart Kiers