Steffan Harris
Steffan Harris

Reputation: 9326

Regex to match vowels in order as they appear once

I trying to figure out a correct regex to match vowels in a word as they appear. There may be any number of consonants in the word; however, there should be no other vowels other than the 5 listed above. For example, the word “sacrilegious” should not match because, although it contains the five vowels in alphabetical order, there is an extra ‘i’ vowel located between the ‘a’ and the ‘e’. Hyphenated words are not allowed. In fact, your regular expression should not match any ‘word’ that contains any character other than the upper and lower case letters.

Here are some words that it should match

abstemious
facetious
arsenious
acheilous
anemious
caesious

This is what I have come up with so far, but when I run the program it doesn't seem to be doing what it should do.

#!/usr/bin/perl -w
use strict;


my $test =  "abstemious";

if( $test =~ /a[^eiou]*e[^aiou]*i[^aeou]*o[^aeiu]u/ )
{

    print "yes";

}

Upvotes: 1

Views: 1725

Answers (5)

toolic
toolic

Reputation: 62154

Here is another approach, if you don't mind making a temporary copy of the string:

use warnings;
use strict;

while (<DATA>) {
    chomp;
    my $test = $_;
    my $cp   = $test; # leave original string intact
    $cp =~ tr/aeiou//cd;
    print "$test\n" if $cp eq 'aeiou';
}

=for output

abstemious
facetious
arsenious
acheilous
anemious
caesious

=cut

__DATA__
abstemious
facetious
arsenious
acheilous
anemious
caesious
unabstemious
sacrilegious
intravenous
faaceetiioouus

Upvotes: 1

Alan Moore
Alan Moore

Reputation: 75242

Is it okay for a word to contain duplicate vowels, as long as they're in the correct order? For example, would faaceetiioouus (if there were such a word) be acceptable? I ask because your current regex does indeed match it.

If you want to match only words that contain exactly one of each vowel, try this:

/^
 (?=[a-z0-9]+$)
 [^aeiou]*a
 [^aeiou]*e
 [^aeiou]*i
 [^aeiou]*o
 [^aeiou]*u
 [^aeiou]*
 $
/ix

Upvotes: 2

Denis de Bernardy
Denis de Bernardy

Reputation: 78513

Try this regexp:

\b(?=[a-zA-Z]+)[^aA]*?[aA][^aeAE]*?[eE][^aeiAEI]*?[iI][^aeioAEIO]*?[oO][^aeiouAEIOU]*?[uU][^aeiouAEIOU]*?\b

Upvotes: 2

anubhava
anubhava

Reputation: 785481

You have a small typo there, try this:

/a[^eiou]*e[^aiou]*i[^aeou]*o[^aeio]*u/

Upvotes: 7

Anomie
Anomie

Reputation: 94834

You're not too far off. Try this regex:

/\b[b-df-hj-np-tv-z]*a[b-df-hj-np-tv-z]*e[b-df-hj-np-tv-z]*i[b-df-hj-np-tv-z]*o[b-df-hj-np-tv-z]*u[b-df-hj-np-tv-z]*\b/i

[b-df-hj-np-tv-z]* matches any number of consonants, then it's just slotting in the vowels and the word boundary markers (\b).

Upvotes: 2

Related Questions