没有符号的正则表达式

时间:2011-11-05 11:20:15

标签: regex lex

我有这个正则表达式:

[-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]*

这用于匹配由空格分隔的单词,如下所示:

 eyes
 yellow
 9+3
 goin$crazy
 mou{s}e

不幸的是,它也匹配这种字符串:

 a${try}b

我希望匹配相同的单词但避免包含序列的所有单词&#34; $ {&#34;。我该怎么办?

修改

在单个正则表达式中执行此操作非常重要,因为我需要使用此正则表达式来定义Flex令牌。

这是flex代码:

%option noyywrap
%option prefix="exp"
%{
#include <stdio.h>
#include <stdlib.h>
#include "expr.tab.h"

char *p; 

extern int yywrap(void);
%}

NUM [0-9]+ 
STR <HERE HAVE TO BE INSERTED THE REGEX I NEED>
VAR $\{[-a-zA-Z][-a-zA-Z0-9]*\}

%%

=           { /*printf("EQ\n");*/ return EQ; }
\)          { /*printf("RPAREN\n");*/ return RPAREN; }
\(          { /*printf("LPAREN\n");*/ return LPAREN; }
\}          { /*printf("KET\n");*/ return KET; }
\{          { /*printf("BRA\n");*/ return BRA; }
"]"         { /*printf("RSBRA\n");*/return RSBRA; }
:           { /*printf("COLON\n");*/ return COLON; }
;           { /*printf("SEMICOLON\n");*/ return SEMICOLON; }
,           { /*printf("COMMA\n");*/ return COMMA; }
"=>"        { /*printf("ARROW\n");*/ return ARROW; }
\|          { /*printf("PIPE\n");*/return PIPE; }
@           { /*printf("AT\n");*/return AT; }
&           { /*printf("AND\n");*/return AND; }
"${"        { /*printf("VARBEGIN\n");*/return VARBEGIN;}
"$["        { /*printf("EXPRINIT\n");*/return EXPRINIT;}
"!="        { /*printf("NOTEQ\n");*/return NOTEQ; }
"=="        {/*printf("EQUAL\n");*/return EQUAL;}
">"         { /*printf("GT\n");*/return GT; }
"<"         { /*printf("LT\n");*/return LT; }
">="        { /*printf("GTEQ\n");*/return GTEQ; }
"<="        { /*printf("LTEQ\n");*/return LTEQ; }
"+"         { /*printf("PLUS\n");*/return PLUS; }
"-"         { /*printf("MINUS\n");*/return MINUS; }
"*"         { /*printf("MULT\n");*/return MULT; }
"/"         { /*printf("DIV\n");*/return DIV; }
"%"         { /*printf("MOD\n");*/return MOD; }
"!"         { /*printf("LOGNOT\n");*/return LOGNOT; }
"=~"        { /*printf("LIKEOP\n");*/return LIKEOP; }
"?"         { /*printf("CONDQUEST\n");*/return CONDQUEST; }

{NUM}   {
    /*printf("VARNAME (%s)\n",yytext);*/
    p = (char*)calloc(strlen(yytext)+1,sizeof(char));
    strcpy(p,yytext);
    yylval = (YYSTYPE)p;
    return NUM;
    }

{VAR}   {
    /*printf("VARNAME (%s)\n",yytext);*/
    p = (char*)calloc(strlen(yytext)+1,sizeof(char));
    strcpy(p,yytext);
    yylval = (YYSTYPE)p;
    return VAR;
    }

{STR}   {
    /*printf("VARNAME (%s)\n",yytext);*/
    p = (char*)calloc(strlen(yytext)+1,sizeof(char));
    strcpy(p,yytext);
    yylval = (YYSTYPE)p;
    return STR;
    }
%%

编辑2 我已经创建了这个规则,它似乎有效,但并不完美,因为它无法匹配仅包含字符的字符串&#34; $&#34;或者只是字符&#34; {&#34;。

(\$[-a-zA-Z0-9"_/.!\*\+\<\>#$}\[\]]|\{[-a-zA-Z0-9"_/.!\*\+\<\>#\$\{}\[\]]|[-a-zA-Z0-9"_/.!\*\+\<\>#}\[\]])*

3 个答案:

答案 0 :(得分:1)

如果您在 STR 之前放置 VAR 怎么办?它不会先赶上吗? (我不懂Flex,但它适用于其他语言)。

无论如何,完整的正则表达式都采用以下形式:

A =没有$

B =没有$且没有{

(A * |(A * $ + BA *)*)$ *导致(A *($ + B)?)* $ *导致([B {] *($ + B) ?)* $ *

答案 1 :(得分:0)

使用专门排除${序列的第二个正则表达式,并将其与not运算符组合使用。虽然可以在一个正则表达式中执行您所要求的操作,但它会变得更复杂,并且在您编写之后第二个将成为不可读的遗留代码。

答案 2 :(得分:0)

正则表达式[-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]*匹配所有符号的序列。因此,您所希望的是以下任意多项的序列:

  • {符号
  • ${之外的任何符号,前面有任意数量的$符号(包括零)

其次是:

  • 任意数量的$符号(包括零)

导致这个正则表达式:

([\{]|[$]*[-a-zA-Z0-9"_/.!\*\+\<\>\}#\[\]])*[$]*

一些额外的[]不是必需的,但我认为它们可以提高清晰度。