POSIX ERE(扩展正则表达式) - 从正则表达式中排除有限的黑名单

时间:2015-12-16 15:25:45

标签: c regex posix

我尝试使用posix来匹配一些5位数的正则表达式:

551..
552..
553..

^(55[123]..)$

但我需要排除下一个数字:

55341 55312 55227

我试图找出如何创建匹配某些数字的正则表达式并使用posix排除另一个(因为我的程序在C中)。

我目前正在使用REG_EXTENDEDREG_ICASE标记编译正则表达式:

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

...并按如下方式执行:

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

4 个答案:

答案 0 :(得分:2)

POSIX正则表达式的唯一方法是艰难的方式(你必须列出所有可能的情况):

^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]))$

(或使用^55[132][0-9][0-9]$并使用简单的if检查禁止的数字

答案 1 :(得分:2)

使用两个正则表达式的逻辑表达式更容易做到这一点。

#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);
}

当一个正则表达式匹配而另一个正则表达不匹配时,您匹配。

s0 == 0 && s1 != 0

答案 2 :(得分:1)

使用2步法而不是尝试使用单个(posix兼容)正则表达式进行求解。

  1. 过滤掉与您的黑名单匹配的所有内容:

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

  2. 使用正则表达式的修改版本批准其余案例:

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

答案 3 :(得分:0)

使用非消耗正则表达式查找以55 [1,2,3]开头的5位数字,然后查看以查看数字是否为黑名单之一。

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

P.S。所有语言都不支持Lookahed