2009-11-14 120 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