2010-06-28 30 views
5

Tôi đang cố gắng phân tích chuỗi đầu vào bằng cách sử dụng cụm từ thông dụng. Tôi đang gặp vấn đề khi cố gắng nắm bắt một nhóm lặp lại. Tôi luôn luôn có vẻ là phù hợp với trường hợp cuối cùng của nhóm. Tôi đã cố gắng sử dụng định lượng Reluctant (không tham lam), nhưng tôi dường như thiếu một cái gì đó. Ai đó có thể giúp đỡ?Làm cách nào để nắm bắt tất cả các kết quả trùng khớp của nhóm lặp lại với Boost :: regex_search?

biểu hiện thường xuyên cố gắng:

(OS)\\s((\\w{3})(([A-Za-z0-9]{2})|(\\w{3})(\\w{3}))\\/{0,1}){1,5}?\\r 

(OS)\\s((\\w{3}?)(([A-Za-z0-9]{2}?)|(\\w{3}?)(\\w{3}?))\\/{0,1}?){1,5}?\\r 

Chuỗi Input:

OS BENKL/LHRBA/MANQFL\r\n 

tôi luôn luôn dường như để có được nhóm cuối cùng đó là MANQFL nhóm (MAN QFL), và mục tiêu của tôi là để có được tất cả ba nhóm (có thể là 1-5 nhóm):

(BEN KL) , (LHR BA) and (MAN QFL). 

Đoạn mã C++:

std::string::const_iterator start = str.begin(), end = str.end(); 
while(regex_search(start,end,what,expr)) 
{ 
    cout << what[0]; 
    cout << what[1]; 
    ... 
    start += what.position() + what.length(); 
} 

Vòng lặp này chỉ xuất hiện một lần, trong khi tôi mong đợi nó chạy 3 lần trong ví dụ này. Bất kỳ trợ giúp sẽ được nhiều đánh giá cao.

+0

Nó sẽ giúp ích rất nhiều nếu bạn cho chúng tôi biết thêm về định dạng của đầu vào và cách bạn muốn phân tích cú pháp. –

+0

Đầu vào là luồng chuỗi và trong ví dụ này, tôi mong đợi nhận được 3 nhóm (BEN KL), (LHR BA) và (MAN QFL). Tôi biết trong trường hợp này chúng ta có thể làm điều đó ngay cả khi không sử dụng các biểu thức thông thường, nhưng tôi chỉ cố gắng xem liệu tôi có thể giữ nó phù hợp với mã hiện tại mà regex được sử dụng hay không. – omshanti

Trả lời

0

Đó là hành vi mong đợi: khi nhóm chụp được kiểm soát bởi một bộ định lượng, mỗi lần lặp lại sẽ ghi đè bất cứ điều gì đã được ghi lại trong lần trước. Cách đơn giản nhất để có được tất cả các trận đấu sẽ được đặt một nhóm chụp xung quanh toàn bộ điều, như thế này:

(OS)\\s(((\\w{3})(([A-Za-z0-9]{2})|(\\w{3})(\\w{3}))\\/?){1,5})\\r 

Đó nhóm sẽ kết thúc chứa BENKL/LHRBA/MANQFL, mà bạn có thể chia nhỏ trên /.

1

Chỉ có một hương vị regex mà tôi biết có thể cung cấp cho bạn tất cả các lần lặp của nhóm chụp là hương vị .NET regex. Thông thường một công cụ regex chỉ lưu lần lặp cuối cùng của mỗi nhóm chụp.

Giải pháp chung cho loại sự cố này là sử dụng một regex để nắm bắt tất cả các lần lặp của nhóm và regex thứ hai để chia kết quả của regex đầu tiên thành các mục riêng biệt. Alan đã giải thích cách bạn có thể làm điều này trong tình huống cụ thể này.

4

Cách tốt nhất để nhận được nhiều kết quả ngoài quảng cáo :: regex là sử dụng regex_iterators. Ví dụ này nên làm những gì bạn muốn.

#include <iostream> 
#include <string> 
#include <boost/regex.hpp> 

int main() { 
    std::string a = "OS BENKL/LHRBA/MANQFL\r\n"; 
    const boost::regex re("[A-Z]{3}[A-Z]*"); 
    boost::sregex_iterator res(a.begin(),a.end(),re); 
    boost::sregex_iterator end; 
    for (; res != end; ++res) 
     std::cout << (*res)[0] << std::endl; 
} 
Các vấn đề liên quan