2012-08-13 35 views
8

Các mã sau đây đánh giá 2 thay vì 4:Đếm trận đấu chồng chéo với Regex trong C#

Regex.Matches("020202020", "020").Count; 

Tôi đoán regex bắt đầu tìm kiếm các trận đấu tiếp theo từ ngày kết thúc trận đấu trước đó. Có cách nào để ngăn chặn điều này. Tôi có một chuỗi '0's và' 2's và tôi đang cố đếm số lần tôi có ba '2 liên tiếp, bốn' 2 liên tiếp, v.v.

+0

Câu hỏi của bạn gây hiểu lầm. Bạn có muốn kết hợp các chuỗi '2'-s liên tiếp hoặc tùy ý không? – krlmlr

Trả lời

8

này sẽ trở lại 4 như bạn mong đợi:

Regex.Matches("020202020", @"0(?=20)").Count; 

Con số nhìn thấy khớp với số 20 mà không cần tiêu thụ, do đó, lần thử đối sánh tiếp theo sẽ bắt đầu ở vị trí sau 0 đầu tiên.Bạn thậm chí có thể làm toàn bộ regex như một lookahead:

Regex.Matches("020202020", @"(?=020)").Count; 

Động cơ regex tự động va vào trước một vị trí mỗi khi nó khớp với độ dài bằng 0. Vì vậy, để tìm tất cả chạy của ba 2 's hoặc bốn 2' s, bạn có thể sử dụng:

Regex.Matches("22222222", @"(?=222)").Count; // 6 

... và:

Regex.Matches("22222222", @"(?=2222)").Count; // 5 

EDIT: Nhìn qua câu hỏi của bạn một lần nữa, nó xảy ra với tôi bạn có thể tìm kiếm 2 's xen kẽ với 0' s

Regex.Matches("020202020", @"(?=20202)").Count; // 2 

Nếu bạn không biết có bao nhiêu 0 's sẽ có, bạn có thể sử dụng này:

Regex.Matches("020202020", @"(?=20*20*2)").Count; // 2 

Và tất nhiên, bạn có thể sử dụng lượng hóa để giảm sự lặp lại trong regex:

Regex.Matches("020202020", @"(?=2(?:0*2){2})").Count; // 2 
4

Thật vậy, một cụm từ thông dụng sẽ tiếp tục từ đâu người cuối cùng đã kết thúc. Bạn có thể làm việc xung quanh nó bằng cách sử dụng các mẫu lookahead. Tôi không phải là một người .NET, nhưng hãy thử: "(?=020)." Dịch: "tìm tôi bất kỳ nhân vật nào, trong đó nhân vật này và hai ký tự tiếp theo là 020". Bí quyết là trận đấu chỉ có một nhân vật rộng, không phải ba, vì vậy bạn sẽ nhận được tất cả các trận đấu trong chuỗi, ngay cả khi chúng trùng nhau.

(bạn cũng có thể viết nó như "0(?=20)", nhưng đó là chưa rõ ràng cho con người ít nhất: p)

0

Giả sử rằng bạn đang thực sự tìm kiếm chuỗi liên tiếp 2 -s, có một tùy chọn mà không sử dụng lookaheads tại tất cả. (Điều này sẽ không làm việc cho chuỗi tùy ý nơi bạn tìm kiếm các mẫu của 02.)

liệt kê tất cả các lần xuất hiện của chuỗi không chồng chéo của ba hoặc nhiều 2 -s (làm thế nào?) Và sau đó suy ra số lượng subsequences ngắn . Ví dụ: nếu bạn tìm thấy một chuỗi gồm sáu số liên tiếp 2 -s và một trong năm số liên tiếp 2 -s, thì bạn biết rằng bạn phải có (6-3 + 1) + (5-3 + 1) = ? trình tự của ba liên tiếp 2 -s (có khả năng chồng chéo), và vân vân:

0002222220000002222200 
    222 
    222 
    222 
     222 
       222 
       222 
       222 

Đối với chuỗi lớn, điều này nên được phần nào nhanh hơn so với sử dụng lookaheads.

-4

Vì nguồn có chứa hai mẫu "020" mà mẫu regex của bạn phù hợp. Hãy thử thay đổi nguồn của bạn thành:

Regex.Matches("020202020", "02").Count; 

Bây giờ, nó sẽ khớp với 02 liên tiếp và bạn sẽ nhận được bốn lần này.

+1

Nó cũng sẽ trả lại kết quả tương tự cho '" 029029029029 "". Tìm kiếm '" 02 "' không tương đương với tìm kiếm '" 020 "'. – Amadan

1

Hãy thử điều này, sử dụng zero-width lookbehind tích cực:

Regex.Matches("020202020",@"(?<=020)").Count; 

Làm việc đối với tôi, sản lượng 4 trận đấu.

tham khảo ưa thích của tôi cho Regex: Regular Expression Language - Quick Reference Cũng là một cách nhanh chóng để thử Regex của bạn, tôi sử dụng nó khá thường xuyên cho Regex phức tạp: Free Regular Expression Designer

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