如何为 flex 生成至少一次所有元音的字符串的正则表达式?
How to generate regular expression for string having all vowels at least once for flex?
您可能认为这是 this 的重复问题。
实际上它是那个问题的类似问题。那我为什么还要问呢?
因为,该问题的公认答案无效。答案可能满足 OP 的要求,但这不是一般答案。
另一个原因是,它应该在 flex 中工作。
我需要一个正则表达式,它只接受那些以任何顺序包含元音的字符串。
它可能有一些其他字母,但所有元音必须至少出现一次。
让我们看一些例子:
String Accepted or Not
---------------------- ---------------
abceioussa Accepted
aeiou Accepted
uioae Accepted
odsidsfusjldkfuuuu Not Accepted
bcesdddsoaiaaau Accepted
aaaaaaaaeeeeeeeooooiu Accepted
aasssssaeeeeeeeoeoooi Not Accepted
编辑:
记住,它应该在 flex
中工作。
编辑 2:
任务:
Pattern Action
------------------------------------------------------------- --------------------
Blank Space, tab space Do nothing
New line Count number of line
Any word contains all five vowels at least once Print VOWELS
Any word ends with s or es Print PLURAL
Any word ends with ly Print ADVERB
Any word ends with ing Print CONTINUOUS
is/do/go/be/are/was/were/did Print VERB
a/an/the Print ARTICLE
Any word starts with uppercase letter and none of the above Print NOUN
Anything else Print NOT_RECOGNIZED
Scanner4.l:
只需要为正则定义填写表达式vowel
。
%{
/* comments */
#define ECHO fwrite(yytext, yyleng,1,yyout);
int yylineno = 0, ii;
%}
letter [a-zA-Z]
uppercase [A-Z]
digit [0-9]
digits [0-9]+
punc [-=\+\_\.,\.\|\~\!$\%\^\&\(\;\'\"\?\{\}\[\]\)\/\#\*@]
anything ({letter}|{digit})
spacetab [\t ]+
endmark [\n\t ]
dot [\.]
hp [\-]
verb (is|do|go|be|are|was|were|did)
article (a|an|the)
normal ({anything}|{punc})
vowel //here you have to write the expression
%option noyywrap
%%
{spacetab}|{punc} {
fprintf(yyout,"%s", yytext);
printf(":%s:%d ECHO\n",yytext,yylineno);
/* do nothing */
}
\n {
yylineno++;
ECHO;
printf(":%s:%d no echo\n",yytext,yylineno);
}
{vowel}{endmark} {
fprintf(yyout," VOWELS ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d vowels\n",yytext,yylineno);
}
{verb}{endmark} {
fprintf(yyout," VERB ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d verb\n",yytext,yylineno);
}
{article}{endmark} {
fprintf(yyout," ARTICLE ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d article\n",yytext,yylineno);
}
{letter}*(s|es){endmark} {
fprintf(yyout," PLURAL ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d plural\n",yytext,yylineno);
}
{letter}*(ly){endmark} {
fprintf(yyout," ADVERB ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d adverb\n",yytext,yylineno);
}
{letter}*(ing){endmark} {
fprintf(yyout," CONTINUOUS ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d continuous\n",yytext,yylineno);
}
{uppercase}{letter}*{endmark} {
fprintf(yyout," NOUN ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d noun\n",yytext,yylineno);
}
{normal}+{endmark} {
fprintf(yyout," NOT_RECOGNIZED%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d as it is\n",yytext,yylineno);
}
%%
int main(){
yyin = fopen("Input4.txt","r");
yyout = fopen("Output4.txt","w");
yylex();
fprintf(yyout, "# of lines = %d\n", yylineno);
fclose(yyin);
fclose(yyout);
return 0;
}
Input4.txt:
aasdfeasdfiasoasdfuasd aeiogedaeido aeiou oeiua aeeeee aeiouuu
speaiously Addoiuea aaaaaaa ing ly
预计Output4.txt:
VOWELS NOT_RECOGNIZED VOWELS VOWELS NOT_RECOGNIZED VOWELS
VOWELS VOWELS NOT_RECOGNIZED CONTINUOUS ly
# of lines = 1
我通过以下命令编译它:
flex Scanner4.l
mingw32-gcc -c lex.yy.c -o Scanner4.yy.o
mingw32-g++ -o Scanner4.yy.exe Scanner4.yy.o
Scanner4.yy
这个基于积极前瞻的正则表达式应该适合你:
\b(?=[[:alpha:]]*[Aa])(?=[[:alpha:]]*[Ee])(?=[[:alpha:]]*[Ii])(?=[[:alpha:]]*[Oo])(?=[[:alpha:]]*[Uu])[[:alpha:]]+\b
(?=\w*a)
强制在单词中出现 a
等或其他前瞻强制所有元音,即 a,e,i,o,u
.
我要使用这个 class [aeiou]
包含英语元音的字符。
[^aeiou]*[aeiou]+...
像上面那样的东西可以工作,但你说它必须包含所有的元音,没有特定的顺序。所以要捕捉这个意图,你需要这样的东西。
[^aeiou]*(a[^eiou]*|e[^aiou]*|i[^aeou]*|o[^aeiu]*|u[^aeio]*)...
现在你明白了吗?我们必须提供很多更改,我们必须将它们嵌套,以表明我们正在寻找迄今为止我们尚未匹配的内容。
我们的想法是 条件 每次更改,然后继续进行,就好像我们可以假设我们不再寻找刚刚匹配的内容一样。没有技巧,只是很多正则表达式。
但是,您需要 (n-1)(n-2)(n-3)... 条款。有 5 个元音它可以工作,但它很好......不理想。
只是为了说明这件事的荒谬性。这是完整的正则表达式。不,我不是手写的,我写了一个小程序来生成它。
[^aeiou]*(a[^eiou]*(e[^iou]*(i[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^iu]*(i[^u]*(u)|u[^i]*(i))|u[^io]*(i[^o]*(o)|o[^i]*(i)))|i[^eou]*(e[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^eu]*(e[^u]*(u)|u[^e]*(e))|u[^eo]*(e[^o]*(o)|o[^e]*(e)))|o[^eiu]*(e[^iu]*(i[^u]*(u)|u[^i]*(i))|i[^eu]*(e[^u]*(u)|u[^e]*(e))|u[^ei]*(e[^i]*(i)|i[^e]*(e)))|u[^eio]*(e[^io]*(i[^o]*(o)|o[^i]*(i))|i[^eo]*(e[^o]*(o)|o[^e]*(e))|o[^ei]*(e[^i]*(i)|i[^e]*(e))))|e[^aiou]*(a[^iou]*(i[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^iu]*(i[^u]*(u)|u[^i]*(i))|u[^io]*(i[^o]*(o)|o[^i]*(i)))|i[^aou]*(a[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ao]*(a[^o]*(o)|o[^a]*(a)))|o[^aiu]*(a[^iu]*(i[^u]*(u)|u[^i]*(i))|i[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ai]*(a[^i]*(i)|i[^a]*(a)))|u[^aio]*(a[^io]*(i[^o]*(o)|o[^i]*(i))|i[^ao]*(a[^o]*(o)|o[^a]*(a))|o[^ai]*(a[^i]*(i)|i[^a]*(a))))|i[^aeou]*(a[^eou]*(e[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^eu]*(e[^u]*(u)|u[^e]*(e))|u[^eo]*(e[^o]*(o)|o[^e]*(e)))|e[^aou]*(a[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ao]*(a[^o]*(o)|o[^a]*(a)))|o[^aeu]*(a[^eu]*(e[^u]*(u)|u[^e]*(e))|e[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ae]*(a[^e]*(e)|e[^a]*(a)))|u[^aeo]*(a[^eo]*(e[^o]*(o)|o[^e]*(e))|e[^ao]*(a[^o]*(o)|o[^a]*(a))|o[^ae]*(a[^e]*(e)|e[^a]*(a))))|o[^aeiu]*(a[^eiu]*(e[^iu]*(i[^u]*(u)|u[^i]*(i))|i[^eu]*(e[^u]*(u)|u[^e]*(e))|u[^ei]*(e[^i]*(i)|i[^e]*(e)))|e[^aiu]*(a[^iu]*(i[^u]*(u)|u[^i]*(i))|i[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ai]*(a[^i]*(i)|i[^a]*(a)))|i[^aeu]*(a[^eu]*(e[^u]*(u)|u[^e]*(e))|e[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ae]*(a[^e]*(e)|e[^a]*(a)))|u[^aei]*(a[^ei]*(e[^i]*(i)|i[^e]*(e))|e[^ai]*(a[^i]*(i)|i[^a]*(a))|i[^ae]*(a[^e]*(e)|e[^a]*(a))))|u[^aeio]*(a[^eio]*(e[^io]*(i[^o]*(o)|o[^i]*(i))|i[^eo]*(e[^o]*(o)|o[^e]*(e))|o[^ei]*(e[^i]*(i)|i[^e]*(e)))|e[^aio]*(a[^io]*(i[^o]*(o)|o[^i]*(i))|i[^ao]*(a[^o]*(o)|o[^a]*(a))|o[^ai]*(a[^i]*(i)|i[^a]*(a)))|i[^aeo]*(a[^eo]*(e[^o]*(o)|o[^e]*(e))|e[^ao]*(a[^o]*(o)|o[^a]*(a))|o[^ae]*(a[^e]*(e)|e[^a]*(a)))|o[^aei]*(a[^ei]*(e[^i]*(i)|i[^e]*(e))|e[^ai]*(a[^i]*(i)|i[^a]*(a))|i[^ae]*(a[^e]*(e)|e[^a]*(a)))))
生成上述正则表达式的代码:
static void Main(string[] args)
{
var vowels = new HashSet<char>("aeiou".ToCharArray());
var sb = new StringBuilder();
BuildRegex(vowels, sb);
Console.WriteLine(sb);
}
private static void BuildRegex(HashSet<char> vowels, StringBuilder sb)
{
if (vowels.Count == 0)
{
return;
}
sb.Append("[^" + string.Join(string.Empty, vowels) + "]*");
if (vowels.Count > 0)
{
sb.Append('(');
int i = 0;
foreach (var vowel in vowels.OrderBy(x => x))
{
var vowels2 = new HashSet<char>(vowels);
vowels2.Remove(vowel);
if (i > 0)
{
sb.Append('|');
}
sb.Append(vowel);
BuildRegex(vowels2, sb);
i++;
}
sb.Append(')');
}
}
static int array[5];
%%
[a-zA-Z] {
int i = 0;
for (i = 0; i < 5' i++ {
array[i] = 0;
}
char a;
i = 0;
for (a = yytext[i]; a != '[=10=]'; i++) {
if (a == 'a') {
array[0] = 1;
}
if (a == 'e') {
array[1] = 1;
}
if (a == 'i') {
array[2] = 1;
}
if (a == 'o') {
array[3] = 1;
}
if (a == 'u') {
array[4] = 1;
}
}
if (array[0] == 1 && array[1] == 1 && array[2] == 1 && array[3] == 1 && array[4] == 1) {
printf("VOWELS\n");
}
}
%%
正则表达式:
a.*e.*i.*o.*u|a.*e.*i.*u.*o|a.*e.*o.*i.*u|a.*e.*o.*u.*i|a.*e.*u.*i.*o|a.*e.*u.*o.*i|a.*i.*e.*o.*u|a.*i.*e.*u.*o|a.*i.*o.*e.*u|a.*i.*o.*u.*e|a.*i.*u.*e.*o|a.*i.*u.*o.*e|a.*o.*e.*i.*u|a.*o.*e.*u.*i|a.*o.*i.*e.*u|a.*o.*i.*u.*e|a.*o.*u.*e.*i|a.*o.*u.*i.*e|a.*u.*e.*i.*o|a.*u.*e.*o.*i|a.*u.*i.*e.*o|a.*u.*i.*o.*e|a.*u.*o.*e.*i|a.*u.*o.*i.*e|e.*a.*i.*o.*u|e.*a.*i.*u.*o|e.*a.*o.*i.*u|e.*a.*o.*u.*i|e.*a.*u.*i.*o|e.*a.*u.*o.*i|e.*i.*a.*o.*u|e.*i.*a.*u.*o|e.*i.*o.*a.*u|e.*i.*o.*u.*a|e.*i.*u.*a.*o|e.*i.*u.*o.*a|e.*o.*a.*i.*u|e.*o.*a.*u.*i|e.*o.*i.*a.*u|e.*o.*i.*u.*a|e.*o.*u.*a.*i|e.*o.*u.*i.*a|e.*u.*a.*i.*o|e.*u.*a.*o.*i|e.*u.*i.*a.*o|e.*u.*i.*o.*a|e.*u.*o.*a.*i|e.*u.*o.*i.*a|i.*a.*e.*o.*u|i.*a.*e.*u.*o|i.*a.*o.*e.*u|i.*a.*o.*u.*e|i.*a.*u.*e.*o|i.*a.*u.*o.*e|i.*e.*a.*o.*u|i.*e.*a.*u.*o|i.*e.*o.*a.*u|i.*e.*o.*u.*a|i.*e.*u.*a.*o|i.*e.*u.*o.*a|i.*o.*a.*e.*u|i.*o.*a.*u.*e|i.*o.*e.*a.*u|i.*o.*e.*u.*a|i.*o.*u.*a.*e|i.*o.*u.*e.*a|i.*u.*a.*e.*o|i.*u.*a.*o.*e|i.*u.*e.*a.*o|i.*u.*e.*o.*a|i.*u.*o.*a.*e|i.*u.*o.*e.*a|o.*a.*e.*i.*u|o.*a.*e.*u.*i|o.*a.*i.*e.*u|o.*a.*i.*u.*e|o.*a.*u.*e.*i|o.*a.*u.*i.*e|o.*e.*a.*i.*u|o.*e.*a.*u.*i|o.*e.*i.*a.*u|o.*e.*i.*u.*a|o.*e.*u.*a.*i|o.*e.*u.*i.*a|o.*i.*a.*e.*u|o.*i.*a.*u.*e|o.*i.*e.*a.*u|o.*i.*e.*u.*a|o.*i.*u.*a.*e|o.*i.*u.*e.*a|o.*u.*a.*e.*i|o.*u.*a.*i.*e|o.*u.*e.*a.*i|o.*u.*e.*i.*a|o.*u.*i.*a.*e|o.*u.*i.*e.*a|u.*a.*e.*i.*o|u.*a.*e.*o.*i|u.*a.*i.*e.*o|u.*a.*i.*o.*e|u.*a.*o.*e.*i|u.*a.*o.*i.*e|u.*e.*a.*i.*o|u.*e.*a.*o.*i|u.*e.*i.*a.*o|u.*e.*i.*o.*a|u.*e.*o.*a.*i|u.*e.*o.*i.*a|u.*i.*a.*e.*o|u.*i.*a.*o.*e|u.*i.*e.*a.*o|u.*i.*e.*o.*a|u.*i.*o.*a.*e|u.*i.*o.*e.*a|u.*o.*a.*e.*i|u.*o.*a.*i.*e|u.*o.*e.*a.*i|u.*o.*e.*i.*a|u.*o.*i.*a.*e|u.*o.*i.*e.*a
只需将点替换为 [a-zA-Z]。
其实flex是做不到的。因为,我尝试了以下但没有成功。
- 起初,我尝试 运行 全部 5 个 flex 程序!组合,但它立即崩溃了!
- 那我运行 flex程序的缩减形式为5!组合了一个多小时,然后就给了
fatal error!
个信息!
所以,我得出结论,flex 是不可能的。
您可能认为这是 this 的重复问题。
实际上它是那个问题的类似问题。那我为什么还要问呢?
因为,该问题的公认答案无效。答案可能满足 OP 的要求,但这不是一般答案。
另一个原因是,它应该在 flex 中工作。
我需要一个正则表达式,它只接受那些以任何顺序包含元音的字符串。
它可能有一些其他字母,但所有元音必须至少出现一次。
让我们看一些例子:
String Accepted or Not
---------------------- ---------------
abceioussa Accepted
aeiou Accepted
uioae Accepted
odsidsfusjldkfuuuu Not Accepted
bcesdddsoaiaaau Accepted
aaaaaaaaeeeeeeeooooiu Accepted
aasssssaeeeeeeeoeoooi Not Accepted
编辑:
记住,它应该在 flex
中工作。
编辑 2:
任务:
Pattern Action
------------------------------------------------------------- --------------------
Blank Space, tab space Do nothing
New line Count number of line
Any word contains all five vowels at least once Print VOWELS
Any word ends with s or es Print PLURAL
Any word ends with ly Print ADVERB
Any word ends with ing Print CONTINUOUS
is/do/go/be/are/was/were/did Print VERB
a/an/the Print ARTICLE
Any word starts with uppercase letter and none of the above Print NOUN
Anything else Print NOT_RECOGNIZED
Scanner4.l:
只需要为正则定义填写表达式vowel
。
%{
/* comments */
#define ECHO fwrite(yytext, yyleng,1,yyout);
int yylineno = 0, ii;
%}
letter [a-zA-Z]
uppercase [A-Z]
digit [0-9]
digits [0-9]+
punc [-=\+\_\.,\.\|\~\!$\%\^\&\(\;\'\"\?\{\}\[\]\)\/\#\*@]
anything ({letter}|{digit})
spacetab [\t ]+
endmark [\n\t ]
dot [\.]
hp [\-]
verb (is|do|go|be|are|was|were|did)
article (a|an|the)
normal ({anything}|{punc})
vowel //here you have to write the expression
%option noyywrap
%%
{spacetab}|{punc} {
fprintf(yyout,"%s", yytext);
printf(":%s:%d ECHO\n",yytext,yylineno);
/* do nothing */
}
\n {
yylineno++;
ECHO;
printf(":%s:%d no echo\n",yytext,yylineno);
}
{vowel}{endmark} {
fprintf(yyout," VOWELS ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d vowels\n",yytext,yylineno);
}
{verb}{endmark} {
fprintf(yyout," VERB ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d verb\n",yytext,yylineno);
}
{article}{endmark} {
fprintf(yyout," ARTICLE ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d article\n",yytext,yylineno);
}
{letter}*(s|es){endmark} {
fprintf(yyout," PLURAL ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d plural\n",yytext,yylineno);
}
{letter}*(ly){endmark} {
fprintf(yyout," ADVERB ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d adverb\n",yytext,yylineno);
}
{letter}*(ing){endmark} {
fprintf(yyout," CONTINUOUS ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d continuous\n",yytext,yylineno);
}
{uppercase}{letter}*{endmark} {
fprintf(yyout," NOUN ");
fprintf(yyout,"%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d noun\n",yytext,yylineno);
}
{normal}+{endmark} {
fprintf(yyout," NOT_RECOGNIZED%c", yytext[yyleng-1]);
if(yytext[yyleng-1]=='\n') yylineno++;
printf(":%s:%d as it is\n",yytext,yylineno);
}
%%
int main(){
yyin = fopen("Input4.txt","r");
yyout = fopen("Output4.txt","w");
yylex();
fprintf(yyout, "# of lines = %d\n", yylineno);
fclose(yyin);
fclose(yyout);
return 0;
}
Input4.txt:
aasdfeasdfiasoasdfuasd aeiogedaeido aeiou oeiua aeeeee aeiouuu
speaiously Addoiuea aaaaaaa ing ly
预计Output4.txt:
VOWELS NOT_RECOGNIZED VOWELS VOWELS NOT_RECOGNIZED VOWELS
VOWELS VOWELS NOT_RECOGNIZED CONTINUOUS ly
# of lines = 1
我通过以下命令编译它:
flex Scanner4.l
mingw32-gcc -c lex.yy.c -o Scanner4.yy.o
mingw32-g++ -o Scanner4.yy.exe Scanner4.yy.o
Scanner4.yy
这个基于积极前瞻的正则表达式应该适合你:
\b(?=[[:alpha:]]*[Aa])(?=[[:alpha:]]*[Ee])(?=[[:alpha:]]*[Ii])(?=[[:alpha:]]*[Oo])(?=[[:alpha:]]*[Uu])[[:alpha:]]+\b
(?=\w*a)
强制在单词中出现 a
等或其他前瞻强制所有元音,即 a,e,i,o,u
.
我要使用这个 class [aeiou]
包含英语元音的字符。
[^aeiou]*[aeiou]+...
像上面那样的东西可以工作,但你说它必须包含所有的元音,没有特定的顺序。所以要捕捉这个意图,你需要这样的东西。
[^aeiou]*(a[^eiou]*|e[^aiou]*|i[^aeou]*|o[^aeiu]*|u[^aeio]*)...
现在你明白了吗?我们必须提供很多更改,我们必须将它们嵌套,以表明我们正在寻找迄今为止我们尚未匹配的内容。
我们的想法是 条件 每次更改,然后继续进行,就好像我们可以假设我们不再寻找刚刚匹配的内容一样。没有技巧,只是很多正则表达式。
但是,您需要 (n-1)(n-2)(n-3)... 条款。有 5 个元音它可以工作,但它很好......不理想。
只是为了说明这件事的荒谬性。这是完整的正则表达式。不,我不是手写的,我写了一个小程序来生成它。
[^aeiou]*(a[^eiou]*(e[^iou]*(i[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^iu]*(i[^u]*(u)|u[^i]*(i))|u[^io]*(i[^o]*(o)|o[^i]*(i)))|i[^eou]*(e[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^eu]*(e[^u]*(u)|u[^e]*(e))|u[^eo]*(e[^o]*(o)|o[^e]*(e)))|o[^eiu]*(e[^iu]*(i[^u]*(u)|u[^i]*(i))|i[^eu]*(e[^u]*(u)|u[^e]*(e))|u[^ei]*(e[^i]*(i)|i[^e]*(e)))|u[^eio]*(e[^io]*(i[^o]*(o)|o[^i]*(i))|i[^eo]*(e[^o]*(o)|o[^e]*(e))|o[^ei]*(e[^i]*(i)|i[^e]*(e))))|e[^aiou]*(a[^iou]*(i[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^iu]*(i[^u]*(u)|u[^i]*(i))|u[^io]*(i[^o]*(o)|o[^i]*(i)))|i[^aou]*(a[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ao]*(a[^o]*(o)|o[^a]*(a)))|o[^aiu]*(a[^iu]*(i[^u]*(u)|u[^i]*(i))|i[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ai]*(a[^i]*(i)|i[^a]*(a)))|u[^aio]*(a[^io]*(i[^o]*(o)|o[^i]*(i))|i[^ao]*(a[^o]*(o)|o[^a]*(a))|o[^ai]*(a[^i]*(i)|i[^a]*(a))))|i[^aeou]*(a[^eou]*(e[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^eu]*(e[^u]*(u)|u[^e]*(e))|u[^eo]*(e[^o]*(o)|o[^e]*(e)))|e[^aou]*(a[^ou]*(o[^u]*(u)|u[^o]*(o))|o[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ao]*(a[^o]*(o)|o[^a]*(a)))|o[^aeu]*(a[^eu]*(e[^u]*(u)|u[^e]*(e))|e[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ae]*(a[^e]*(e)|e[^a]*(a)))|u[^aeo]*(a[^eo]*(e[^o]*(o)|o[^e]*(e))|e[^ao]*(a[^o]*(o)|o[^a]*(a))|o[^ae]*(a[^e]*(e)|e[^a]*(a))))|o[^aeiu]*(a[^eiu]*(e[^iu]*(i[^u]*(u)|u[^i]*(i))|i[^eu]*(e[^u]*(u)|u[^e]*(e))|u[^ei]*(e[^i]*(i)|i[^e]*(e)))|e[^aiu]*(a[^iu]*(i[^u]*(u)|u[^i]*(i))|i[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ai]*(a[^i]*(i)|i[^a]*(a)))|i[^aeu]*(a[^eu]*(e[^u]*(u)|u[^e]*(e))|e[^au]*(a[^u]*(u)|u[^a]*(a))|u[^ae]*(a[^e]*(e)|e[^a]*(a)))|u[^aei]*(a[^ei]*(e[^i]*(i)|i[^e]*(e))|e[^ai]*(a[^i]*(i)|i[^a]*(a))|i[^ae]*(a[^e]*(e)|e[^a]*(a))))|u[^aeio]*(a[^eio]*(e[^io]*(i[^o]*(o)|o[^i]*(i))|i[^eo]*(e[^o]*(o)|o[^e]*(e))|o[^ei]*(e[^i]*(i)|i[^e]*(e)))|e[^aio]*(a[^io]*(i[^o]*(o)|o[^i]*(i))|i[^ao]*(a[^o]*(o)|o[^a]*(a))|o[^ai]*(a[^i]*(i)|i[^a]*(a)))|i[^aeo]*(a[^eo]*(e[^o]*(o)|o[^e]*(e))|e[^ao]*(a[^o]*(o)|o[^a]*(a))|o[^ae]*(a[^e]*(e)|e[^a]*(a)))|o[^aei]*(a[^ei]*(e[^i]*(i)|i[^e]*(e))|e[^ai]*(a[^i]*(i)|i[^a]*(a))|i[^ae]*(a[^e]*(e)|e[^a]*(a)))))
生成上述正则表达式的代码:
static void Main(string[] args)
{
var vowels = new HashSet<char>("aeiou".ToCharArray());
var sb = new StringBuilder();
BuildRegex(vowels, sb);
Console.WriteLine(sb);
}
private static void BuildRegex(HashSet<char> vowels, StringBuilder sb)
{
if (vowels.Count == 0)
{
return;
}
sb.Append("[^" + string.Join(string.Empty, vowels) + "]*");
if (vowels.Count > 0)
{
sb.Append('(');
int i = 0;
foreach (var vowel in vowels.OrderBy(x => x))
{
var vowels2 = new HashSet<char>(vowels);
vowels2.Remove(vowel);
if (i > 0)
{
sb.Append('|');
}
sb.Append(vowel);
BuildRegex(vowels2, sb);
i++;
}
sb.Append(')');
}
}
static int array[5];
%%
[a-zA-Z] {
int i = 0;
for (i = 0; i < 5' i++ {
array[i] = 0;
}
char a;
i = 0;
for (a = yytext[i]; a != '[=10=]'; i++) {
if (a == 'a') {
array[0] = 1;
}
if (a == 'e') {
array[1] = 1;
}
if (a == 'i') {
array[2] = 1;
}
if (a == 'o') {
array[3] = 1;
}
if (a == 'u') {
array[4] = 1;
}
}
if (array[0] == 1 && array[1] == 1 && array[2] == 1 && array[3] == 1 && array[4] == 1) {
printf("VOWELS\n");
}
}
%%
正则表达式:
a.*e.*i.*o.*u|a.*e.*i.*u.*o|a.*e.*o.*i.*u|a.*e.*o.*u.*i|a.*e.*u.*i.*o|a.*e.*u.*o.*i|a.*i.*e.*o.*u|a.*i.*e.*u.*o|a.*i.*o.*e.*u|a.*i.*o.*u.*e|a.*i.*u.*e.*o|a.*i.*u.*o.*e|a.*o.*e.*i.*u|a.*o.*e.*u.*i|a.*o.*i.*e.*u|a.*o.*i.*u.*e|a.*o.*u.*e.*i|a.*o.*u.*i.*e|a.*u.*e.*i.*o|a.*u.*e.*o.*i|a.*u.*i.*e.*o|a.*u.*i.*o.*e|a.*u.*o.*e.*i|a.*u.*o.*i.*e|e.*a.*i.*o.*u|e.*a.*i.*u.*o|e.*a.*o.*i.*u|e.*a.*o.*u.*i|e.*a.*u.*i.*o|e.*a.*u.*o.*i|e.*i.*a.*o.*u|e.*i.*a.*u.*o|e.*i.*o.*a.*u|e.*i.*o.*u.*a|e.*i.*u.*a.*o|e.*i.*u.*o.*a|e.*o.*a.*i.*u|e.*o.*a.*u.*i|e.*o.*i.*a.*u|e.*o.*i.*u.*a|e.*o.*u.*a.*i|e.*o.*u.*i.*a|e.*u.*a.*i.*o|e.*u.*a.*o.*i|e.*u.*i.*a.*o|e.*u.*i.*o.*a|e.*u.*o.*a.*i|e.*u.*o.*i.*a|i.*a.*e.*o.*u|i.*a.*e.*u.*o|i.*a.*o.*e.*u|i.*a.*o.*u.*e|i.*a.*u.*e.*o|i.*a.*u.*o.*e|i.*e.*a.*o.*u|i.*e.*a.*u.*o|i.*e.*o.*a.*u|i.*e.*o.*u.*a|i.*e.*u.*a.*o|i.*e.*u.*o.*a|i.*o.*a.*e.*u|i.*o.*a.*u.*e|i.*o.*e.*a.*u|i.*o.*e.*u.*a|i.*o.*u.*a.*e|i.*o.*u.*e.*a|i.*u.*a.*e.*o|i.*u.*a.*o.*e|i.*u.*e.*a.*o|i.*u.*e.*o.*a|i.*u.*o.*a.*e|i.*u.*o.*e.*a|o.*a.*e.*i.*u|o.*a.*e.*u.*i|o.*a.*i.*e.*u|o.*a.*i.*u.*e|o.*a.*u.*e.*i|o.*a.*u.*i.*e|o.*e.*a.*i.*u|o.*e.*a.*u.*i|o.*e.*i.*a.*u|o.*e.*i.*u.*a|o.*e.*u.*a.*i|o.*e.*u.*i.*a|o.*i.*a.*e.*u|o.*i.*a.*u.*e|o.*i.*e.*a.*u|o.*i.*e.*u.*a|o.*i.*u.*a.*e|o.*i.*u.*e.*a|o.*u.*a.*e.*i|o.*u.*a.*i.*e|o.*u.*e.*a.*i|o.*u.*e.*i.*a|o.*u.*i.*a.*e|o.*u.*i.*e.*a|u.*a.*e.*i.*o|u.*a.*e.*o.*i|u.*a.*i.*e.*o|u.*a.*i.*o.*e|u.*a.*o.*e.*i|u.*a.*o.*i.*e|u.*e.*a.*i.*o|u.*e.*a.*o.*i|u.*e.*i.*a.*o|u.*e.*i.*o.*a|u.*e.*o.*a.*i|u.*e.*o.*i.*a|u.*i.*a.*e.*o|u.*i.*a.*o.*e|u.*i.*e.*a.*o|u.*i.*e.*o.*a|u.*i.*o.*a.*e|u.*i.*o.*e.*a|u.*o.*a.*e.*i|u.*o.*a.*i.*e|u.*o.*e.*a.*i|u.*o.*e.*i.*a|u.*o.*i.*a.*e|u.*o.*i.*e.*a
只需将点替换为 [a-zA-Z]。
其实flex是做不到的。因为,我尝试了以下但没有成功。
- 起初,我尝试 运行 全部 5 个 flex 程序!组合,但它立即崩溃了!
- 那我运行 flex程序的缩减形式为5!组合了一个多小时,然后就给了
fatal error!
个信息!
所以,我得出结论,flex 是不可能的。