2009-11-14 38 views
0

我在设置正则表达式来匹配使用C中的regex.h库的URL时遇到了一些困难。我有一个正在工作的IP正则表达式,我希望将其转换为匹配一个简单的字符串,如www.alphanumerictext12.com|edu|org。正则表达式定义本身的语法有些问题。这个正则表达式匹配URL有什么问题?

下面是工作IPREGEX代码和我尝试的URL正则表达式。

#define IPEXPR "([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})" 
#define URLEXPR "(www)\\.((?:[a-z][a-z]*[0-9]+[a-z0-9]*))\\.(com|edu|org)" 

regex_t regex; 

if(regcomp(&regex, IPEXPR, REG_EXTENDED) != 0) 
    return 0; 

if(regexec(&regex, inputURL, 0, NULL, 0) != 0) 
    return 0; 
+0

好吧,我已经更新了我的正则表达式:“^(www | www1){1} \\。[a-z0-9] + [_] * [ - ] * [a-z0-9] * \\。(com | edu | org)$“这对任何我抛出的东西都非常有用,除了大小写不敏感......我的编译器不关心:”(?i)^(www | www1){1 } \\。[a-z0-9] + [_] * [ - ] * [a-z0-9] * \\。(com | edu | org)$“改善此字符串的建议?再次感谢大家,CB – 2009-11-16 16:37:41

+0

我试着将REG_ICASE标志添加到regexec()和regcomp(),但没有运气....建议? CB – 2009-11-16 17:04:46

+0

REG_ICASE应该可以工作。您是否尝试过regcomp(&regex,URLEXPR,REG_EXTENDED | REG_ICASE)? 而且,你能告诉我们你的目标是什么?你正在构建真正奇怪的正则表达式......它仅适用于域名的一小部分...... – 2009-11-16 18:15:54

回答

2

尝试:

"www\\.[a-z]+[a-z0-9]*\\.(com|edu|org)" 

我删除了[0-9]+[a-z]+更换[a-z][a-z]*

+0

我希望这是不区分大小写的,下面会更好一些吗? :“www \\。[a-zA-Z] + [a-zA-Z0-9] * \\。(com | edu | org)” – 2009-11-16 15:13:54

+1

您可以这样做,但不会允许.COM '或'.eDu'作为顶级域名。你可以通过在你的正则表达式前面添加'(?i)'标志来启用不区分大小写的匹配:'“(?i)www \\。[az] + [a-z0-9] * \\。 edu | org)“'假设你正在使用的正则表达式库支持'(?i)'。 – 2009-11-16 15:53:19

+0

我在Ubuntu上使用c中的regex.h。我会给(?)一个测试。 “www \\。[az] + [a-z0-9] * \\。(com | edu | org)”正在令人愉快地工作,现在我需要添加字符 - 和_我在哪里放置他们在?我试图将它们加入,如[a-z0-9-_]但失败。我在这里观看什么关键?谢谢大家,CB – 2009-11-16 16:12:44

1

问题出在(?:),您只需要(www)\\.([a-z][a-z]*[0-9]+[a-z0-9]*)\\.(com|edu|org)

顺便说一下,你的内心表达说:“至少有一个字母字符,然后至少有一个数字字符,然后是任何字母数字字符”。这是你的意思吗?如果是这样,你可以缩短一点:[a-z]+[0-9]+[a-z0-9]*

+0

“至少有一个字母字符,然后至少有一个数字字符,然后是任何字母数字字符”。这是你的意思吗?不,这将是一个错误。 我会给你的正则表达式尝试并报告回来,谢谢! CB – 2009-11-16 15:12:04

+0

然后你可能更喜欢[az] + [a-z0-9] *,但要注意,域名可以以数字开头:) – 2009-11-16 15:48:30

-2

Coding Horror

一些人,当遇到一个问题,认为 “我知道,我将使用 正则表达式。”现在他们有 两个问题。

我的意思是:你确定正则表达式是解决问题的最好方法吗?也许你可以测试这个字符串是否是一个带有更多轻量级方法的URL?


编辑

我的电脑下面的程序,具有输出重定向到/dev/null,打印(到stderr

 
rx time: 1.730000 
lw time: 0.920000 

计划清单:

#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <regex.h> 
#include <string.h> 
#include <time.h> 

int goodurl_rx(const char *buf) { 
    static regex_t rx; 
    static int done = 0; 
    int e; 

    if (!done) { 
    done = 1; 
    if ((e = regcomp(&rx, "^www\\.[a-z][a-z0-9]*\\.(com|edu|org)$", REG_EXTENDED)) != 0) { 
     printf("Error %d compiling regular expression.\n", e); 
     exit(EXIT_FAILURE); 
    } 
    } 
    return !regexec(&rx, buf, 0, NULL, 0); 
} 

int goodurl_lw(const char *buf) { 
    if (*buf++ != 'w') return 0; 
    if (*buf++ != 'w') return 0; 
    if (*buf++ != 'w') return 0; 
    if (*buf++ != '.') return 0; 
    if (!isalpha((unsigned char)*buf++)) return 0; 
    while (isalnum((unsigned char)*buf)) buf++; 
    if (*buf++ != '.') return 0; 
    if ((*buf == 'c') && (*(buf+1) == 'o') && (*(buf+2) == 'm') && (*(buf+3) == 0)) return 1; 
    if ((*buf == 'e') && (*(buf+1) == 'd') && (*(buf+2) == 'u') && (*(buf+3) == 0)) return 1; 
    if ((*buf == 'o') && (*(buf+1) == 'r') && (*(buf+2) == 'g') && (*(buf+3) == 0)) return 1; 
    return 0; 
} 

int main(void) { 
    clock_t t0, t1, t2; 
    char *buf[] = {"www.alphanumerics.com", "ww2.alphanumerics.com", "www.alphanumerics.net"}; 
    int times; 

    t0 = clock(); 
    times = 1000000; 
    while (times--) { 
    printf(" %s: %s\n", buf[0], goodurl_rx(buf[0])?"pass":"invalid"); 
    printf(" %s: %s\n", buf[1], goodurl_rx(buf[1])?"pass":"invalid"); 
    printf(" %s: %s\n", buf[2], goodurl_rx(buf[2])?"pass":"invalid"); 
    }; 
    t1 = clock(); 
    times = 1000000; 
    while (times--) { 
    printf(" %s: %s\n", buf[0], goodurl_lw(buf[0])?"pass":"invalid"); 
    printf(" %s: %s\n", buf[1], goodurl_lw(buf[1])?"pass":"invalid"); 
    printf(" %s: %s\n", buf[2], goodurl_lw(buf[2])?"pass":"invalid"); 
    } while (0); 
    t2 = clock(); 

    fprintf(stderr, "rx time: %f\n", (double)(t1-t0)/CLOCKS_PER_SEC); 
    fprintf(stderr, "lw time: %f\n", (double)(t2-t1)/CLOCKS_PER_SEC); 
    return 0; 
} 
+0

嗯,在这种情况下,我相信一个正则表达式是最好的答案,但是我我肯定会接受有效的建议。我以通用格式输入用户的网址:www.alphanumerics.com。你能建议一个更轻量级的方法吗? – 2009-11-16 15:20:34

+0

pmg,几乎可以肯定这个函数是用来验证用户输入的,所以在这里真正无关紧要。 但是关于开发时间,可读性,可支持性等呢?稍做修改就需要重写你的代码,最后是自制的FSA。 – 2009-11-16 20:07:54

+0

对于这个简单的例子,我同意正则表达式函数更容易处理。然而,有一天,当你想要“接受”co.uk和net.au时,使'ads *。*'失效,而不是'cads *。*'',...,...;也不会很好。当发生这种情况时,解析器是最好的选择,但是基于正则表达式的解决方案IMVHO倾向于使用正则表达式:更多和更尴尬。 – pmg 2009-11-16 21:26:45

0

您可能应该使用inet_pton()这是一个标准的POSIX功能(替换inet_aton())并处理IPv4和IPv6地址格式。

+0

我不确定我完全理解这个用法。这是否是一种更有尊严的方式来检查IP地址与我目前使用的正则表达式的有效性? (以上定义为IPEXPR) CB – 2009-11-16 15:18:16

+0

是的,尤其是因为IPv6具有inet_pton将处理的缩写形式。这不仅仅是0-9和。 – dajobe 2009-11-16 21:17:08

相关问题