Luiz Fernando Softov
Luiz Fernando Softov

Reputation: 43

POSIX ERE (extended regex) -- excluding a limited blacklist from a regex

I'm trying to do a regex using posix to match some numbers of 5 digits:

551..
552..
553..

^(55[123]..)$

But i need to exclude the next numbers:

55341 55312 55227

I'm trying to figure out how to create a regex that match some numbers and exclude another using posix (because my program is in C).


I'm currently compiling the regex with REG_EXTENDED and REG_ICASE flags:

status  = regcomp(&brb_regex->reg, regex_str, REG_EXTENDED|REG_ICASE);

...and executing it as follows:

status  = regexec(&brb_regex->reg, cmp_str, 10, brb_regex->match, 0);

Upvotes: 3

Views: 544

Answers (4)

Ziffusion
Ziffusion

Reputation: 8933

It's easier to do this using a logical expression of two regexes.

#include <sys/types.h>
#include <regex.h>
#include <stdio.h>

int main() {
    regex_t r0, r1;
    regmatch_t rm[10];
    int s0, s1;

    s0 = regcomp(&r0, "^55[123]..$", REG_EXTENDED|REG_ICASE);
    s0 = regcomp(&r1, "^(55341)|(55312)|(55227)$", REG_EXTENDED|REG_ICASE);

    s0 = regexec(&r0, "55188", 10, rm, 0);
    s1 = regexec(&r1, "55188", 10, rm, 0);
    printf("===== %d %d match=%d\n", s0, s1, s0 == 0 && s1 != 0);

    s0 = regexec(&r0, "55341", 10, rm, 0);
    s1 = regexec(&r1, "55341", 10, rm, 0);
    printf("===== %d %d match=%d\n", s0, s1, s0 == 0 && s1 != 0);
}

You have a match when one regex matches and the other doesn't.

s0 == 0 && s1 != 0

Upvotes: 2

Giuseppe Ricupero
Giuseppe Ricupero

Reputation: 6272

Use a 2 steps approach instead of trying to solve with a single (posix-compatible) regex.

  1. Filter out everything that matches your black list:

    ^(55341|55312|55227)$ # you can easily add new values

  2. Use a modified version of your regex to approve the remaining cases:

    ^55[1-3][0-9]{2}$

Upvotes: 1

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89629

The only way with POSIX regex is the hard way (you must list all possible cases):

^55(1[0-9][0-9]|2([013-9][0-9]|2[0-689])|3([0235-9][0-9]|1[013-9]|4[02-9]))$

(or use ^55[132][0-9][0-9]$ and check forbidden numbers with a simple if)

Upvotes: 3

Kaspars Primaks
Kaspars Primaks

Reputation: 82

Use non consuming regex to find 5 digit numbers that start with 55[1,2,3] and then lookahed to check of number isn't one of blacklisted.

^(?=55[123]\d{2})((?!55(341|312|227))\d){5}$

P.S. Lookahed is not supported by all language

Upvotes: 0

Related Questions