1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Ajuda com regex

Discussão em 'Programação' iniciada por MPalhas, 1 de Maio de 2009. (Respostas: 3; Visualizações: 836)

  1. MPalhas

    MPalhas Power Member

    estou a fazer um trabalho para a universidade em C em que preciso de ler de um ficheiro um conjunto de regras que vão ser usadas para controlar o decorrer do programa (simular o crescimento de uma cidade)
    não posso assumir que o ficheiro está escrito correctamente, ou seja, tenho que detectar erros de sintaxe nas regras.
    o problema para já esta em validar as condições que são do género destas:
    Código:
    s = F | P
    C>= 2
    C < 5
    s = F|P
    R>=2
    R < 5
    já consegui ler o ficheiro de forma a ler uma unica condição para uma string, para a tratar individualmente, mas não estou a conseguir validá-la para verificar se esta bem escrita. o problema está naquele pipe ( | ) como na primeira condição, que significa "se s for igual a F ou P..."

    fiz esta expressão para tentar validar com regex,usando o regex.h
    Código:
    ^s=[RCEAFG]([|][RCEAFG])*$
    onde RCEAFG são os unicos caracteres que são validos nas condiçoes. este regex serve apenas para as condições que começam por "s=" pois as outras sao tratadas em separado.
    o problema é que já testei esta expressão em vários sites que encontrei e parece estar a funcionar bem, mas no programa em C não funciona.
    obrigado a quem me puder ajudar.

    já agora, caso não tenha explicado bem, aqui estão alguns exemplos de expressões que o regex deve validar
    Código:
    s=E
    s=E|A
    s=E|E|G
    e as que nao pode validar
    Código:
    s=
    s=|
    s=EA
    s=E||A
    EDIT: tinha-me esquecido. aqui está a funçao que uso para executar o regex. praticamente copiada de um exemplo que encontrei, pois ainda não estudei isto muito a fundo
    Código:
    int regexMatch(const char *string, char *regexPattern) {
        int status;
        regex_t re;
    
        if (regcomp(&re, regexPattern, REG_NOSUB) != 0) {
            return 0;
        }
        status = regexec(&re, string, (size_t) 0, NULL, 0);
        
        regfree(&re);
        
        if (status != 0) {
            return 0;
        }
        return 1;
    }
     
    Última edição: 1 de Maio de 2009
  2. AliFromCairo

    AliFromCairo Power Member

    Boas, a regex que colocaste não permite espaços, o que faz com que algumas das expressões que aí colocaste não façam match.
     
  3. MPalhas

    MPalhas Power Member

    não é dai o problema, porque ao ler a string do ficheiro eu excluo logo os espaços e tabs. além disso eu para ja estou so a fazer testes fazendo:

    Código:
    printf("%d", regexMatch(string, pattern));
    onde a string e o pattern têm valores dados por mim, e não lidos do ficheiro
     
  4. slack_guy

    slack_guy Power Member

    Se estás a usar Linux podes instalar o módulo Perl Explain que poderá ser-te útil para trabalhares com expressões regulares.

    Por exemplo:
    Código:
    $ perl -MYAPE::Regex::Explain -e '$exp=YAPE::Regex::Explain->new("^s=[RCEAFG]([|][RCEAFG])*\$")->explain;print $exp'
    
    The regular expression:
    
    (?-imsx:^s=[RCEAFG]([|][RCEAFG])*$)
    
    matches as follows:
    
    NODE                     EXPLANATION
    ----------------------------------------------------------------------
    (?-imsx:                 group, but do not capture (case-sensitive)
                             (with ^ and $ matching normally) (with . not
                             matching \n) (matching whitespace and #
                             normally):
    ----------------------------------------------------------------------
      ^                        the beginning of the string
    ----------------------------------------------------------------------
      s=                       's='
    ----------------------------------------------------------------------
      [RCEAFG]                 any character of: 'R', 'C', 'E', 'A', 'F',
                               'G'
    ----------------------------------------------------------------------
      (                        group and capture to \1 (0 or more times
                               (matching the most amount possible)):
    ----------------------------------------------------------------------
        [|]                      any character of: '|'
    ----------------------------------------------------------------------
        [RCEAFG]                 any character of: 'R', 'C', 'E', 'A',
                                 'F', 'G'
    ----------------------------------------------------------------------
      )*                       end of \1 (NOTE: because you're using a
                               quantifier on this capture, only the LAST
                               repetition of the captured pattern will be
                               stored in \1)
    ----------------------------------------------------------------------
      $                        before an optional \n, and the end of the
                               string
    ----------------------------------------------------------------------
    )                        end of grouping
    ----------------------------------------------------------------------
    
    EDIT:
    O que é 'não funciona'? Algum erro? não apanha as strings (in)válidas?
     
    Última edição: 1 de Maio de 2009

Partilhar esta Página