2011-11-05 91 views
2

我有這樣的正則表達式:正則表達式不帶符號

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

這是用來匹配空間這樣的分隔的單詞:

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

不幸的是,也符合這樣的字符串:

a${try}b 

我希望匹配相同的單詞,但避免包含序列「$ {」的所有單詞。我該怎麼做?

編輯

這是做一個單一的正則表達式真的很重要,因爲這樣的事實,我需要這個正則表達式可以用來定義柔性令牌。

這裏是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; 
    } 
%% 

EDIT 2 我創造了這個規則,它似乎工作,但不是完美的,因爲它不能夠匹配僅包含字符串「$ 「或只有字符」{「。

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

我無法理解您對單詞的定義。 – FailedDev

+0

在這種情況下,只是一個字符序列匹配的正則表達式,我已經發布,但我想迫使它不包含字符序列「$ {」 –

回答

0

請使用專門排除${序列的第二正則表達式,並與運營商not結合起來。雖然可以在一個正則表達式中執行所要求的操作,但它會複雜得多,並且會在寫入後成爲不可讀的遺留代碼。

+0

我需要這個正則表達式爲一個flex令牌,那麼它應該做一個獨特的正則表達式。 –

+0

好的,但你不能使用字符類,因爲他們沒有任何上下文的概念。你需要消極的後視聲明或者一個大的分解符:類似於「不是'前面有'$'或者任何其他允許的單詞符號',並且把量詞應用於整個事物。如果你甚至沒有外掛,你需要兩個大字符類,並將量詞僅應用於第二個 - 醜陋!這就是爲什麼我討厭強迫你用單個正則表達式來做東西的工具。 –

+0

我很遺憾地知道這是醜陋的,但我沒有在flex中「隱藏」不了的操作符,並且可以請您發佈您想到的正則表達式嗎? –

1

如果您在VAR之前STR怎麼辦?它不會先捕獲嗎? (我不知道Flex,但它在其他語言中有效)。

無論如何,全正則表達式是在這種形式:

A =無$

B =無$和不{

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

+0

VAR在規則定義中已經放在字符串之前。 Flex只有在兩個標記能夠匹配相同長度的字符串時才考慮規則的優先級,否則首先考慮匹配最長字符串的規則。 關於您發佈的規則,似乎用這個規則,我無法匹配有效字符串「$ a {b} c $」這樣的詞 –

+0

因此,我忘了攜帶1 :)。只需要在正則表達式的末尾添加$ *即可:([B {] *($ + B)?)* $ * – OmegaZiv

+0

生成的正則表達式爲'([-a-zA-Z0-9'_ /。 !\ * \ + \ <\>#$} \ [\]] *($ + [ - a-zA-Z0-9「_ /。!\ * \ + \ <\>#} \ [\]])?)* $ *'但它不符合建議示例中的任何一個。 –

0

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

  • {符號
  • 除了${,通過任何數量的$符號之前的任何符號(包括零)

其次:

  • 任意數量的$符號(包括零)

在這個表達式得到的:

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

一些額外[] S的不是必要的,但我認爲他們提高清晰度。

+0

嘗試這個正則表達式,它似乎也匹配包含序列的字符串「$ {」 –

+0

哦,現在我明白這是可能的,但它實際上匹配最後的'$',而不是下面的'{'。如果你刪除尾部的'[$] *',它會更好,但是你會在匹配字符串的末尾遺漏所有'$'s。你不能用簡單的正則表達式來完成一個完美的amswer,但我會檢查解決這個問題的方法。 –