Ajuda com regex

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:
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
 
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:
(...) mas no programa em C não funciona.
O que é 'não funciona'? Algum erro? não apanha as strings (in)válidas?
 
Última edição:
Back
Topo