evkline evkline - 2 months ago 19
Ruby Question

Using Regexp to check whether a string starts with a consonant

Is there a better way to write the following regular expression in Ruby? The first regex matches a string that begins with a (lower case) consonant, the second with a vowel.

I'm trying to figure out if there's a way to write a regular expression that matches the negative of the second expression, versus writing the first expression with several ranges.

string =~ /\A[b-df-hj-np-tv-z]/
string =~ /\A[aeiou]/


The statement

$string =~ /\A[^aeiou]/

will test whether the string starts with a non-vowel character, which includes digits, punctuation, whitespace and control characters. That is fine if you know beforehand that the string begins with a letter, but to check that it starts with a consonant you can use forward look-ahead to test that it starts with both a letter and a non-vowel, like this

$string =~ /\A(?=[^aeiou])(?=[a-z])/i

To match an arbitrary number of consonants, you can use the sub-expression (?i:(?![aeiou])[a-z]) to match a consonant. It is atomic, so you can put a repetition count like {3} right after it. For example, this program finds all the strings in a list that contain three consonants in a row

list = %w/ aab bybt xeix axei AAsE SAEE eAAs xxsa Xxsr /

puts list.select { |word| word =~ /\A(?i:(?![aeiou])[a-z]){3}/ }