Lauren Bolin
Lauren Bolin

Reputation: 43

Regex: match if vowels occur in a word in order (aeiou), and not match if there is a char other than a char

I am trying to match if a word has aeiou and it has to be in order of aeiou. It also is not supposed to match if there is a char that is not a word. For example:

Match:

cabeilous

Not Match:

sacrilegious 
jeious 
cabeil-ous

This is what I have so far:

.a[^e]*e[^i]*i[^o]*o[^u]*u.

this is matching on sacrilegious.

Upvotes: 2

Views: 310

Answers (3)

ggorlen
ggorlen

Reputation: 57115

/^[^\Waeiou]*a[^\Waeiou]*e[^\Waeiou]*i[^\Waeiou]*o[^\Waeiou]*u[^\Waeiou]*$/

should do the trick. Anchor both sides of the string and exclude any non-word characters and anything out of place. You can allow repetitions such as aeeiou by excluding each vowel from the character class immediately following it.

const pattern = /^[^\Waeiou]*a[^\Waeiou]*e[^\Waeiou]*i[^\Waeiou]*o[^\Waeiou]*u[^\Waeiou]*$/;

[
  "cabeilous",    // yep
  "sacrilegious", // nope
  "jeious",       // nope
  "cabeil-ous",   // nope
  "aaeiou",       // nope
  "aeeiou",       // nope
  "aeiiou",       // nope
  "aeioou",       // nope
  "aeiouu",       // nope
].forEach(test => console.log(test, pattern.test(test)));

const patternWithReps = /^[^\Waeiou]*a[^\Weiou]*e[^\Waiou]?i[^\Waeou]*?o[^\Waeiu]*?u[^\Waeio]*$/;

console.log("\n~~ with repetition: ~~");

[
  "cabeilous",    // yep
  "sacrilegious", // nope
  "jeious",       // nope
  "cabeil-ous",   // nope
  "aaeiou",       // yep
  "aeeiou",       // yep
  "aeiiou",       // yep
  "aeioou",       // yep
  "aeiouu",       // yep
].forEach(test => console.log(test, patternWithReps.test(test)));

Upvotes: 1

Emma
Emma

Reputation: 27733

This expression might help you to pass your desired output, and fail others:

^([a-z]+)?(?:[a-z]*a(?:[a-z]*e(?:[a-z]*i(?:[a-z]*o(?:[a-z]*u)))))([a-z]+)?$

Here, we can use a layer by layer architecture to check every letter in order, then we can add a list of chars for those we wish to have behind it. I've just assumed that [a-z] might be a desired list of char.

enter image description here

RegEx

If this wasn't your desired expression, you can modify/change your expressions in regex101.com.

RegEx Circuit

You can also visualize your expressions in jex.im:

enter image description here

JavaScript Demo for Capturing Groups

const regex = /^([a-z]+)?(?:[a-z]*a(?:[a-z]*e(?:[a-z]*i(?:[a-z]*o(?:[a-z]*u)))))([a-z]+)?$/gm;
const str = `aeiou
cabeilous
zaaefaifoafua
sacrilegious 
jeious 
cabeil-ous`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Upvotes: 0

tripleee
tripleee

Reputation: 189618

You have to exclude all the other vowels in each negation if that's what you actually want.

Upvotes: 1

Related Questions