2013-07-20 248 views
0

我不認爲我明白如何只返回匹配的正則表達式。我有一個網頁文件。我正在嘗試獲取頁面中的所有鏈接。正則表達式工作正常。但是,如果我打印出來,它會打印出匹配發生的行。我只想顯示比賽。我看到你可以做分組,所以我嘗試了,並且爲我的第二次printf調用返回一個int值。根據文件它是一個抵消。但抵消了什麼?它看起來並不準確,要麼是因爲當該行的字符32與正則表達式無關時它會說32。我只是看到第一場比賽就退出了。我哪裏錯了?regmatch_t我怎樣才能得到匹配?

char line[1000]; 
    FILE *fp_original; 
    fp_original = fopen (file_original_page, "r"); 

    regex_t re_links; 
    regmatch_t group[2]; 
    regcomp (&re_links, "(href|src)=[\"|'][^\"']*[\"|']", REG_EXTENDED); 

    while (fgets (line, sizeof line, fp_original) != NULL) { 
    if (regexec (&re_links, line, 2, group, 0) == 0) { 
     printf ("%s", line); 
     printf ("%u\n", line[group[1].rm_so]); 
     exit (1); 
    } 
    } 

    fclose (fp_original); 
+1

當我與一個匹配的輸入運行程序,它打印'104',這是不是一個偏移,但*是*在發現該字符的偏移量! (這是匹配字符串的第一個字符的'href'的'h'的ASCII碼。)你是否通過打印'line [group [i] .rm_so]'而不是'group [i] .rm_so'? –

+0

@ WumpusQ.Wumbley你說得對,'line [group [1] .rm_so]'確實返回ascii碼。但是當我嘗試使用'group [1] .rm_so'時,我得到一個警告:'警告:格式'%u'期望輸入'unsigned int',但參數2的類型爲'regoff_t''。任何想法爲什麼? – user983223

+0

我可以告訴你如何解決這個問題,但我想先解決其他問題。對用戶來說沒有意義的警告消息是一個問題。警告應該包含您需要的所有信息。從我的角度來看,它確實如此。我無法想象*不瞭解它。你有機會通過解釋你的思維過程來幫助那些將來處於你的位置的人,現在,在混亂離開你之前,你成爲我們中的一員... –

回答

3

regmatch_t陣列

regmatch_t是matcharray,你傳遞給正則表達式電話。如果我們傳遞2作爲正則表達式中的匹配數,我們在regmatch_t [0]中獲得整個匹配,並在regmatch_t [1]中獲得子匹配。

例如:

size_t nmatch = 2; 
regmatch_t pmatch[2]; 

rc = regex(&re_links, line, nmatch, pmatch, 0); 

如果成功了,你可以得到的子表達式如下:

pmatch[1].rm_eo - pmatch[1].rm_so, &line[pmatch[1].rm_so], 
pmatch[1].rm_so, pmatch[1].rm_eo - 1); 

這裏是如何應用上面的例子:

#include <regex.h>                
#include <stdio.h>                
#include <stdlib.h>                

int main(void)                 
{                     
    regex_t preg;                

    char *string = "I'm a link to somewhere";        
    char *pattern = ".*\\(link\\).*";          

    size_t  nmatch = 2;               
    regmatch_t pmatch[2];               


    regcomp(&preg, pattern, 0);             
    regexec(&preg, string, nmatch, pmatch, 0);          

    printf("a matched substring \"%.*s\" is found at position %d to %d.\n",  
    pmatch[1].rm_eo - pmatch[1].rm_so, &string[pmatch[1].rm_so], 
    pmatch[1].rm_so, pmatch[1].rm_eo - 1);         

    regfree(&preg);                

    return 0;                  
}  

以上代碼肯定不會保存。它只是作爲一個例子。如果你與你的團隊交換pmatch,它應該工作。另外不要忘了加上括號,你想在你的小組捕捉到你的正則表達式的一部分 - >\\(.*\\)

編輯

爲了避免編譯器有關領域的精度,可以警告與此更換整個printf的一部分:

char *result; 

result = (char*)malloc(pmatch[1].rm_eo - pmatch[1].rm_so); 
strncpy(result, &string[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so); 

printf("a matched substring \"%s\" is found at position %lld to %lld.\n", 
     result, pmatch[1].rm_so, pmatch[1].rm_eo - 1); 

// later on ... 
free(result); 
+0

當我運行上面的操作時,出現錯誤。 test.c:在函數'main'中: test.c:21:warning:字段精度應該是'int'類型,但是參數2的類型是'regoff_t' test.c:21:warning:format'%d '期望類型'int',但參數4的類型'regoff_t' test.c:21:warning:格式'%d'期望類型'int',但參數5類型'regoff_t'' – user983223

+0

這很奇怪,因爲這在我的網站上完美運行,甚至使用不同的gcc版本......你確定你使用了完全相同的代碼嗎? – Stefan

+0

@ user983223首先,這些是警告,而不是錯誤,但我同意你的看法,它們很醜,並且避免警告消息可以被認爲是強制性的。看看我的編輯如何避免這些... – Stefan

1

結果匹配(您的group)爲您提供了開始索引和結束索引。你只需要打印這兩個indeces之間的項目。

group[0]將是整個正則表達式的匹配。隨後的組將會是你在正則表達式中的任何捕獲。

for(int i = 0; i < re_links.re_nsub; ++i) { 
    printf("match %d from index %d to %d: ", i, group[i].rm_so, group[i].rm_eo); 

    for(int j = group[i].rm_so; j < group[i].rm_eo; ++j) { 
     printf("%c", line[j]); 
    } 
    printf("\n"); 
} 

有關完整的示例,請參閱我的回答here