您可能认为这是this的重复问题。
实际上这是一个类似的问题。那我为什么要再问一次呢?
因为,该问题的接受答案不起作用。答案可能符合OP的要求,但这不是一般答案。
另一个原因是,它应该在flex中工作。
我需要一个正则表达式,它只接受那些包含任意顺序元音的字符串。
它可能有其他一些字母,但所有元音必须至少出现一次。
让我们看一些例子:
String Accepted or Not
---------------------- ---------------
abceioussa Accepted
aeiou Accepted
uioae Accepted
odsidsfusjldkfuuuu Not Accepted
bcesdddsoaiaaau Accepted
aaaaaaaaeeeeeeeooooiu Accepted
aasssssaeeeeeeeoeoooi Not Accepted
请记住,它应该适用于flex
。
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
看一下只需填写常规定义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;
}
aasdfeasdfiasoasdfuasd aeiogedaeido aeiou oeiua aeeeee aeiouuu
speaiously Addoiuea aaaaaaa ing ly
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
答案 0 :(得分:2)
我将使用包含英语元音的这个字符类[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(')');
}
}
答案 1 :(得分:1)
这种基于前瞻性的正面正则表达式适用于你:
\b(?=[[:alpha:]]*[Aa])(?=[[:alpha:]]*[Ee])(?=[[:alpha:]]*[Ii])(?=[[:alpha:]]*[Oo])(?=[[:alpha:]]*[Uu])[[:alpha:]]+\b
(?=\w*a)
强制a
出现在单词中,以及强制执行所有元音的其他前瞻,即a,e,i,o,u
。
答案 2 :(得分:1)
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 != '\0'; 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]替换点。
答案 3 :(得分:0)
实际上这是不可能的flex。因为,我试过以下没有运气。
fatal error!
消息!所以,我已经得出结论,决定使用flex是不可能的。