the vowels do not have to appear consecutively. The string bonfire should match, but beak and yearbook should not.
I tried using
grep -P '([aeiouy][aeiouy]*){3}'
but it only seems to work when the vowels are consecutive.
the vowels do not have to appear consecutively. The string bonfire should match, but beak and yearbook should not.
I tried using
grep -P '([aeiouy][aeiouy]*){3}'
but it only seems to work when the vowels are consecutive.
This job can be done easily using awk without using any regex. Just set field separator to one of the vowels and then make sure we have 4 fields:
awk -F '[aeiouy]' 'NF == 4' file
PS: y is not really a vowel but included because of your shown example.
Use [^aeiouy] to match non-vowels. Put a sequence of these around each vowel pattern.
grep -x '[^aeiouy]*[aeiouy][^aeiouy]*[aeiouy][^aeiouy]*[aeiouy][^aeiouy]*' filename
Use the -x option to match the whole line, or anchor the regexp with ^ and $.
You don't need PCRE, this only uses traditional regexp patterns.
You don't need -P for Perl-compatible regular expressions.
If you want to match exactly 3 vowels using grep, you can use anchors and match 3 vowels surrounded by optional repetitions of the negated character class [^aeiouy]* matching any character except the vowels.
grep '^[^aeiouy]*\([aeiouy][^aeiouy]*\)\{3\}$' file
Or with -E
grep -E '^[^aeiouy]*([aeiouy][^aeiouy]*){3}$' file
If you want at least 3 vowels:
grep -E '([aeiouy][^aeiouy]*){2}[aeiouy]' file
Using any awk:
$ echo 'bonfire' | awk 'gsub(/[aeiouy]/,"&")==3'
bonfire
$ echo 'beak' | awk 'gsub(/[aeiouy]/,"&")==3'
$ echo 'yearbook' | awk 'gsub(/[aeiouy]/,"&")==3'
$