2016-08-09 23 views
6

Tôi đang sử dụng regex khi tôi sử dụng nó trên vỏ nó hoạt động nhưng không phải bên trong chương trình C.Regex không hoạt động trong C

Bạn nghĩ gì?

echo "abc:[email protected]" | grep -E "(\babc\b|\bdef\b):[0-9]{10}@([A-Za-z0-9].*)" //shell 

reti = regcomp(&regex,"(\babc\b|\bdef\b):[0-9]{10}@([A-Za-z0-9].*)", 0); //c program 
+5

'grep -E' sử dụng ERE cú pháp (Tôi nghĩ rằng đó là gần ERE, với một số cải tiến). Chuyển cờ 'REG_EXTENDED' vào' regcomp'. Tuy nhiên, tôi không chắc chắn '\ b' được hỗ trợ bởi' regex.h'. –

+0

Phiên bản C của bạn sử dụng dấu gạch chéo ngược đơn bên trong một chuỗi C. Điều đó sẽ không hoạt động, vì những dấu gạch chéo ngược đó không được chuyển vào thư viện regex của bạn. (Đó là?) – usr2564301

Trả lời

3

grep -E sử dụng một số cải tiến cú pháp ERE nghĩa là {n,m} niềng răng lượng hóa (và cũng ()) không cần phải được thoát (không phải là trường hợp trong BRE regex).

Bạn cần phải vượt qua REG_EXTENDED cờ đến regcomp và cũng vì bạn không thể sử dụng đường biên từ, hãy thay thế \b đầu tiên bằng (^|[^[:alnum:]_]) "tương đương". Bạn không cần trailing \b kể từ khi có một : trong mẫu ngay sau:

const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)"; 

Phần (^|[^[:alnum:]_]) phù hợp với một trong hai đầu của chuỗi (^) hoặc (|) một char khác ngoài chữ và số hoặc dấu gạch dưới.

Full C demo:

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

int main (void) 
{ 
    int match; 
    int err; 
    regex_t preg; 
    regmatch_t pmatch[4]; 
    size_t nmatch = 4; 
    const char *str_request = "abc:[email protected]"; 

    const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)"; 
    err = regcomp(&preg, str_regex, REG_EXTENDED); 
    if (err == 0) 
    { 
     match = regexec(&preg, str_request, nmatch, pmatch, 0); 
     nmatch = preg.re_nsub; 
     regfree(&preg); 
     if (match == 0) 
     { 
      printf("\"%.*s\"\n", pmatch[2].rm_eo - pmatch[2].rm_so, &str_request[pmatch[2].rm_so]); 
      printf("\"%.*s\"\n", pmatch[3].rm_eo - pmatch[3].rm_so, &str_request[pmatch[3].rm_so]); 
     } 
     else if (match == REG_NOMATCH) 
     { 
      printf("unmatch\n"); 
     } 
    } 
    return 0; 
} 
+0

Plus 1. Cảm ơn rất nhiều Wiktor Stribiżew. Nó đã giúp tôi rất nhiều. Trân trọng. – CppLearner

+0

Tuyệt vời.Chỉ cần nhớ rằng 'regmatch_t pmatch [4]' và 'size_t nmatch = 4' phụ thuộc vào số lượng nhóm chụp được xác định trong mẫu:' 4' = 1 + số lượng các nhóm '(...)' * chụp *. –

1

Lời Boundary Reference

General
POSIX

Từ liên kết ở trên nó xuất hiện POSIX hỗ trợ riêng của nó ranh giới từ xây dựng.
Lưu ý rằng các cấu trúc này [[:<:]], [[:>:]]không phải là các lớp.

Cho rằng, và sử dụng ERE như trái ngược với BRE, bạn sẽ có thể để làm điều này -

reti = regcomp(&regex,"[[:<:]](abc|def)[[:>:]]:[0-9]{10}@([A-Za-z0-9].*)", REG_EXTENDED);

hay, kể từ giữa [cf]: là một ranh giới từ tự nhiên, nó có thể được giảm xuống

reti = regcomp(&regex,"[[:<:]](abc|def):[0-9]{10}@([A-Za-z0-9].*)", REG_EXTENDED);

Tôi chưa thử nghiệm nhưng nó có thể hoạt động.
Và thực tế là không rõ ràng về nội dung này trong nội bộ, có thể tốt hơn là
gắn với cú pháp này.

Một số công cụ, như Boost mà có tùy chọn POSIX, tùy chỉnh cú pháp để \<\>

Các vấn đề liên quan