Reputation: 34215
I am looking for a regex pattern I want to use in my php name generator script.
It should detect if the string contains three consecutive consonants. But it should not detect the string if two consecutive consonants of the three consecutive consonants are the same.
Example:
"hello" -> False, because there aren't 3 consecutive consonants.
"matching" -> True, because there are 3 consecutive consonants.
"apple" -> False, although there are 3 consecutive consonants, because two consecutive of them are the same.
Please help me to find such a regex pattern.
Upvotes: 4
Views: 4721
Reputation: 6136
(([b-df-hj-np-tv-z])(?!\2)){3}
http://gskinner.com/RegExr/?2vtnt
Edit
There's an edge case with this pattern that it fails if it's proceeded by the same last consonant.
E.g xyzz
should match xyz
but doesn't.
This would be a more accurate pattern.
(([b-df-hj-np-tv-z])(?!\2)){2}[b-df-hj-np-tv-z]
Upvotes: 6
Reputation: 16441
This can be done with a negative assertion and a lookback:
1. Use the lookback to build an expression to match two identical characters: (.)\1
.
2. Add .?
, before it, to catch the pair either immediately or after a character: .?(.)\1
.
3. 3 consecutive consonants: [b-df-hj-np-tv-z]{3}
4. Add #2 above as a negative assertion: (?!.?(.)\1)[b-df-hj-np-tv-z]{3}
.
I took some parts from @zapthedingbat's answer, which is more elagant, but (I think) errs a bit.
Upvotes: 2
Reputation: 32701
/([bcdfghjklmnpqrstvwxyz]{3})/i
This will match 3 consonants in a row. And then str_split
the match and check whether all three items are different.
preg_match_all('/([bcdfghjklmnpqrstvwxyz]{3})/i', $string, $matches);
foreach ($matches[0] as $match) {
$items = str_split(strtolower($match));
if ($items[0] != $items[1] && $items[1] != $items[2]) {
// match
}
}
Upvotes: 0
Reputation: 17234
This will work.
/([^aeiou]{3})/i
^
in the class means it should NOT comtain a,e,i,o,u
Upvotes: 1