2010-04-05 63 views
19

我想從另一個使用正則表達式提取字符串。 我使用POSIX正則表達式函數(regcomp, regexec ...),我在拍攝一組失敗...你如何用正則表達式捕獲一個組?

例如,我們的模式是一樣簡單的東西"MAIL FROM:<(.*)>"
(與REG_EXTENDED CFLAGS)

我想「<」之間捕捉一切和「>」

我的問題是regmatch_t給我的整個模式的邊界(MAIL FROM:< ...>),而不是括號之間只是什麼...

我錯過了什麼?

由於提前,

編輯:一些代碼

#define SENDER_REGEX "MAIL FROM:<(.*)>" 

int main(int ac, char **av) 
{ 
    regex_t regex; 
    int status; 
    regmatch_t pmatch[1]; 

    if (regcomp(&regex, SENDER_REGEX, REG_ICASE|REG_EXTENDED) != 0) 
    printf("regcomp error\n"); 
    status = regexec(&regex, av[1], 1, pmatch, 0); 
    regfree(&regex); 
    if (!status) 
     printf( "matched from %d (%c) to %d (%c)\n" 
      , pmatch[0].rm_so 
      , av[1][pmatch[0].rm_so] 
      , pmatch[0].rm_eo 
      , av[1][pmatch[0].rm_eo] 
      ); 

    return (0); 
} 

輸出:

$./a.out "MAIL FROM:<abcd>$" 
matched from 6 (M) to 22 ($) 

溶液:

如RarrRarrRarr說,指數確實在pmatch[1].rm_sopmatch[1].rm_eo
因此regmatch_t pmatch[1];變得regmatch_t pmatch[2];
regexec(&regex, av[1], 1, pmatch, 0);變得regexec(&regex, av[1], 2, pmatch, 0);

謝謝:)

回答

9

regmatch_t結構的pmatch陣列的第0個元素將包含正如您已經注意到的,整個字符串的邊界匹配。在您的示例中,您對索引1處的regmatch_t感興趣,而不是索引0,以便通過子表達式獲取有關字符串匹配的信息。

如果您需要更多幫助,請嘗試編輯您的問題以包含實際的小代碼示例,以便人們可以更輕鬆地發現問題。

+0

謝謝,這是問題:) – Sylvain 2010-04-05 06:52:16

16

下面是演示捕獲多個組的代碼示例。

你可以看到組'0'是整個匹配,後面的組是括號內的部分。

請注意,這將只捕獲源字符串中的第一個匹配項。 Here's a version that captures multiple groups in multiple matches

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

int main() 
{ 
    char * source = "___ abc123def ___ ghi456 ___"; 
    char * regexString = "[a-z]*([0-9]+)([a-z]*)"; 
    size_t maxGroups = 3; 

    regex_t regexCompiled; 
    regmatch_t groupArray[maxGroups]; 

    if (regcomp(&regexCompiled, regexString, REG_EXTENDED)) 
    { 
     printf("Could not compile regular expression.\n"); 
     return 1; 
    }; 

    if (regexec(&regexCompiled, source, maxGroups, groupArray, 0) == 0) 
    { 
     unsigned int g = 0; 
     for (g = 0; g < maxGroups; g++) 
     { 
      if (groupArray[g].rm_so == (size_t)-1) 
      break; // No more groups 

      char sourceCopy[strlen(source) + 1]; 
      strcpy(sourceCopy, source); 
      sourceCopy[groupArray[g].rm_eo] = 0; 
      printf("Group %u: [%2u-%2u]: %s\n", 
       g, groupArray[g].rm_so, groupArray[g].rm_eo, 
       sourceCopy + groupArray[g].rm_so); 
     } 
    } 

    regfree(&regexCompiled); 

    return 0; 
} 

輸出:

Group 0: [ 4-13]: abc123def 
Group 1: [ 7-10]: 123 
Group 2: [10-13]: def