我一直在C中使用正则表达式(仅/usr/include/regex.h
)。
我有(比方说)数百个正则表达式,其中一个可以匹配输入字符串。 目前我正在这样做(实际上是生成它):数百个内部匹配的do-while,如果不匹配就会中断并转到另一个。一个接一个:
do {
if ( regex_match(str, my_regex1) != MY_REGEX_SUCCESS ) DO_FAIL; //break
...
if ( sscanf(str, " %d.%d.%d.%d / %d ", &___ip1, &___ip2, &___ip3, &___ip4, &___pref) != 5 ) DO_FAIL; //break
...
} while (0);
do {
if ( regex_match(str, my_regex2) != MY_REGEX_SUCCESS ) DO_FAIL; //break
...
...
} while (0);
do {
if ( regex_match(str, my_regex3) != MY_REGEX_SUCCESS ) DO_FAIL; //break
...
...
} while (0);
我想拥有的是:
const char * match1 = "^([[:space:]]*)([$]([._a-zA-Z0-9-]{0,118})?[._a-zA-Z0-9])([[:space:]]*)$";
const char * match2 = "^([[:space:]]*)(target|origin)([[:space:]]*):([[:space:]]*)([$]([._a-zA-Z0-9-]{0,118})?[._a-zA-Z0-9])([[:space:]]*):([[:space:]]*)\\*([[:space:]]*)$";
const char * match3 = "^([[:space:]]*)(target|origin)([[:space:]]*):([[:space:]]*)([$]([._a-zA-Z0-9-]{0,118})?[._a-zA-Z0-9])([[:space:]]*)/([[:space:]]*)(([0-2]?[0-9])|(3[0-2]))([[:space:]]*):([[:space:]]*)(([1-9][0-9]{0,3})|([1-5][0-9]{4})|(6[0-4][0-9]{3})|(65[0-4][0-9]{2})|(655[0-2][0-9])|(6553[0-5]))([[:space:]]*)$";
char * my_match;
asprintf(&my_match, "(%s)|(%s)|(%s)", match1, match2, match3);
int num_gr = give_me_number_of_regex_group(str, my_match)
switch (num_gr) {
...
}
并且不知道该怎么做......
有什么建议吗? 谢谢!
答案 0 :(得分:5)
我认为您的regex_match
是regcomp
和regexec
的某种组合。要启用分组,您需要使用regcomp
标志调用REG_EXTENDED
,但不要使用REG_NOSUB
标志(在第三个参数中)。
regex_t compiled;
regcomp(&compiled, "(match1)|(match2)|(match3)", REG_EXTENDED);
然后为组分配空间。组的数量存储在compiled.re_nsub
中。将此号码传递给regexec
:
size_t ngroups = compiled.re_nsub + 1;
regmatch_t *groups = malloc(ngroups * sizeof(regmatch_t));
regexec(&compiled, str, ngroups, groups, 0);
现在,第一个无效组是rm_so
和rm_eo
字段中值为-1的组:
size_t nmatched;
for (nmatched = 0; nmatched < ngroups; nmatched++)
if (groups[nmatched].rm_so == (size_t)(-1))
break;
nmatched
是匹配的带括号的子表达式(组)的数量。添加自己的错误检查。
答案 1 :(得分:0)
你可以让他们给你一个包含你的regexp的字符串数组并测试每一个。
//count is the number of regexps provided
int give_me_number_of_regex_group(const char *needle,const char** regexps, int count ){
for(int i = 0; i < count; ++i){
if(regex_match(needle, regexp[i])){
return i;
}
}
return -1; //didn't match any
}
还是我在监督什么?
答案 2 :(得分:0)
“我(让我们说)数百个正则表达式......”
看起来你正在尝试比较ip地址的四边形部分。通常,在使用正则表达式时,在单个目标上使用多个正则表达式并在匹配后停止时,它通常是一个红色标记。
示例:哪个组首先正确匹配?
target ~'American' , pattern ~ /(Ame)|(Ameri)|(American)/
这甚至不包括子组中的量词。
如果它是一个常量形式的情况,正则表达式由/来自例如数据组成,那么使用C的字符串函数将表单中的数据拆分成数组可能会更好,然后将数组项与目标。 C比正则表达式要快得多。