Регулярное выражение без символов - PullRequest
2 голосов
/ 05 ноября 2011

У меня есть это регулярное выражение:

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

Используется для сопоставления слов, разделенных пробелами, например:

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

К сожалению, это соответствует и этому виду строки:

 a${try}b

Я хочу сопоставить одни и те же слова, но избегать всех слов, содержащих последовательность "$ {". Как я могу это сделать?

EDIT

Действительно важно сделать это в одном регулярном выражении, потому что мне нужно, чтобы это регулярное выражение использовалось для определения гибкого токена.

Вот гибкий код:

%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 Я создал это правило, и оно, кажется, работает, но не идеально, потому что оно не может соответствовать строке, содержащей только символ "$" или только символ "{".

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

Ответы [ 3 ]

1 голос
/ 05 ноября 2011

Что если вы поместите VAR до STR ?Разве это не поймать первым?(Я не знаю Flex, но он работает на других языках).

Независимо от этого, полное регулярное выражение имеет следующую форму:

A = без $

B =без $ и без {

(A * | (A * $ + BA *) *) $ *, ведущий к (A * ($ + B)?) * $ *, ведущему к ([B{] * ($ + B)?) * $ *

0 голосов
/ 05 ноября 2011

Регулярное выражение [-a-zA-Z0-9"_/.!\*\+\<\>\{\}$#\[\]]* соответствует последовательности всех символов. Поэтому вы хотите последовательность произвольно многих из следующих элементов:

  • либо символ {
  • или любой символ, кроме $ или {, которому предшествует любое количество $ символов (включая ноль)

Далее:

  • любое количество $ символов (включая ноль)

В результате этого регулярного выражения:

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

Некоторые дополнительные [] не нужны, но я думаю, что они улучшают ясность.

0 голосов
/ 05 ноября 2011

Используйте второе регулярное выражение, которое специально исключает последовательность ${, и объедините его с оператором not. Хотя можно выполнить то, что вы просите, за одно регулярное выражение, это намного сложнее и станет нечитаемым устаревшим кодом через секунду после того, как вы его напишите.

...