POSIX ERE(扩展正则表达式)——从正则表达式中排除有限的黑名单
POSIX ERE (extended regex) -- excluding a limited blacklist from a regex
我正在尝试使用 posix 做一个正则表达式来匹配一些 5 位数的数字:
551..
552..
553..
^(55[123]..)$
但我需要排除下一个数字:
55341 55312 55227
我正在尝试弄清楚如何创建一个正则表达式来匹配一些数字并使用 posix 排除另一个(因为我的程序是在 C 中)。
我目前正在使用 REG_EXTENDED
和 REG_ICASE
标志编译正则表达式:
status = regcomp(&brb_regex->reg, regex_str, REG_EXTENDED|REG_ICASE);
...并按如下方式执行:
status = regexec(&brb_regex->reg, cmp_str, 10, brb_regex->match, 0);
使用非消耗性正则表达式查找以 55[1,2,3] 开头的 5 位数号码,然后检查号码是否在黑名单中。
^(?=55[123]\d{2})((?!55(341|312|227))\d){5}$
P.S。并非所有语言都支持 Lookahed
使用 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 检查禁用数字)
使用两步法,而不是尝试使用单个(posix 兼容的)正则表达式来解决。
过滤掉符合您的黑名单的所有内容:
^(55341|55312|55227)$ # you can easily add new values
使用正则表达式的修改版本来批准剩余的案例:
^55[1-3][0-9]{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
我正在尝试使用 posix 做一个正则表达式来匹配一些 5 位数的数字:
551..
552..
553..
^(55[123]..)$
但我需要排除下一个数字:
55341 55312 55227
我正在尝试弄清楚如何创建一个正则表达式来匹配一些数字并使用 posix 排除另一个(因为我的程序是在 C 中)。
我目前正在使用 REG_EXTENDED
和 REG_ICASE
标志编译正则表达式:
status = regcomp(&brb_regex->reg, regex_str, REG_EXTENDED|REG_ICASE);
...并按如下方式执行:
status = regexec(&brb_regex->reg, cmp_str, 10, brb_regex->match, 0);
使用非消耗性正则表达式查找以 55[1,2,3] 开头的 5 位数号码,然后检查号码是否在黑名单中。
^(?=55[123]\d{2})((?!55(341|312|227))\d){5}$
P.S。并非所有语言都支持 Lookahed
使用 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 检查禁用数字)
使用两步法,而不是尝试使用单个(posix 兼容的)正则表达式来解决。
过滤掉符合您的黑名单的所有内容:
^(55341|55312|55227)$ # you can easily add new values
使用正则表达式的修改版本来批准剩余的案例:
^55[1-3][0-9]{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