2014-11-02 22 views
19

Dưới đây chương trình đã được ghi để tìm nạp thông tin "Ngày" bằng cách sử dụng C++ 11 std::regex_match & std::regex_search. Tuy nhiên, sử dụng phương thức đầu tiên trả về false và phương thức trả về thứ hai true (dự kiến). Tôi đọc tài liệu và câu hỏi SO hiện có liên quan đến điều này, nhưng tôi không hiểu sự khác biệt giữa hai phương pháp này và khi nào chúng ta nên sử dụng một trong hai phương pháp này? Cả hai có thể được sử dụng thay thế cho nhau cho bất kỳ vấn đề chung nào không?Sự khác biệt giữa std :: regex_match & std :: regex_search?

Difference between regex_match and regex_search?

#include<iostream> 
#include<string> 
#include<regex> 

int main() 
{ 
    std::string input{ "Mon Nov 25 20:54:36 2013" }; 
    //Day:: Exactly Two Number surrounded by spaces in both side 
    std::regex r{R"(\s\d{2}\s)"}; 
    //std::regex r{"\\s\\d{2}\\s"}; 
    std::smatch match; 

if (std::regex_match(input,match,r)) { 
     std::cout << "Found" << "\n"; 
    } else { 
     std::cout << "Did Not Found" << "\n"; 
    } 

    if (std::regex_search(input, match,r)) { 
     std::cout << "Found" << "\n"; 
     if (match.ready()){ 
      std::string out = match[0]; 
      std::cout << out << "\n"; 
     } 
    } 
    else { 
     std::cout << "Did Not Found" << "\n"; 
    } 
} 

Output

Did Not Found 

Found 

25 

Tại sao đầu tiên phương pháp regex trả false trong trường hợp này ?. Các regex có vẻ là chính xác như vậy lý tưởng cả hai nên đã được trả lại true. Tôi đã chạy chương trình trên bằng cách thay đổi std::regex_match(input,match,r) thành std::regex_match(input,r) và thấy rằng nó vẫn trả về false.

Ai đó có thể giải thích ví dụ trên và, nói chung, trường hợp sử dụng các phương pháp này?

Trả lời

18

regex_match chỉ trả lại true khi toàn bộ chuỗi đầu vào được khớp, trong khi regex_search sẽ thành công ngay cả khi chỉ có một chuỗi phụ khớp với regex.

Trích dẫn từ N3337,

§28.11.2/2regex_match[re.alg.match]

Effects: Xác định xem có một trận đấu giữa biểu thức chính quy etất cả chuỗi ký tự [first,last). ... Trả về true nếu có một kết quả như vậy, false nếu không.

Mô tả ở trên dành cho quá trình tải xuống regex_match mất một cặp vòng lặp cho chuỗi được khớp. Các tình trạng quá tải còn lại được xác định trong điều kiện quá tải này.

Các tương ứng regex_search quá tải được mô tả như

§28.11.3/2regex_search[re.alg.search]

Effects: Xác định xem có một số phụ trình tự trong phạm vi [first,last) khớp với cụm từ thông dụng e. ... Trả về true nếu một chuỗi như vậy tồn tại, false nếu không.


Trong ví dụ của bạn, nếu bạn sửa đổi regex-r{R"(.*?\s\d{2}\s.*)"}; cả regex_matchregex_search sẽ thành công (nhưng kết quả trận đấu không chỉ là ban ngày, nhưng toàn bộ chuỗi ngày).

Live demo của phiên bản được sửa đổi của ví dụ của bạn khi ngày đó đang được chụp và hiển thị bởi cả hai regex_matchregex_search.

+0

Cảm ơn bạn đã giải thích. Bạn có thể giải thích về lý do tại sao chúng tôi cần thay đổi từ trận đấu [0] thành [1] để có kết quả chính xác trong cả hai trường hợp ?. Tôi có nghĩa là nó là về std :: smatch sử dụng sự hiểu biết. –

+1

@MantoshKumar Tôi đã thêm dấu ngoặc đơn xung quanh trường ngày '(\ d {2})' để tạo nhóm chụp. Từ 'match_results' [documentation] (http://en.cppreference.com/w/cpp/regex/match_results/operator_at),' match [0] 'luôn trả về toàn bộ biểu thức được khớp, trong khi' match [1] ' trả về kết quả phù hợp đầu tiên và v.v. Trong trường hợp này, chúng tôi chỉ có một nhóm chụp, trong ngày, và do đó được lưu trữ trong trận đấu phụ đầu tiên. – Praetorian

12

Rất đơn giản. regex_search xem qua chuỗi để tìm xem có phần nào của chuỗi khớp với regex hay không. regex_match kiểm tra xem toàn bộ chuỗi có phù hợp với regex hay không. Như một ví dụ đơn giản, do chuỗi sau:

"one two three four" 

Nếu tôi sử dụng regex_search vào đó chuỗi với các biểu hiện "three", nó sẽ thành công, bởi vì "three" có thể được tìm thấy trong "one two three four"

Tuy nhiên, nếu tôi sử dụng regex_match thay vào đó, nó sẽ thất bại, bởi vì "three" không phải là toàn bộ chuỗi, nhưng chỉ là một phần của nó.

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