2010-10-01 22 views
6

Làm cách nào tôi có thể sử dụng lookbehind trong C# Regex để bỏ qua các kết hợp của các mẫu tiền tố lặp lại?Làm cách nào tôi có thể sử dụng lookbehind trong C# Regex để bỏ qua các kết hợp của các mẫu tiền tố lặp lại?

Ví dụ - Tôi đang cố gắng để có trận đấu biểu hiện tất cả các ký tự sau b bất kỳ số lượng a ký tự:

Regex expression = new Regex("(?<=a).*"); 

foreach (Match result in expression.Matches("aaabbbb")) 
    MessageBox.Show(result.Value); 

lợi nhuận aabbbb, các lookbehind chỉ một a phù hợp. Làm thế nào tôi có thể làm cho nó để nó sẽ phù hợp với tất cả các a s trong đầu?

Tôi đã thử

Regex expression = new Regex("(?<=a+).*"); 

Regex expression = new Regex("(?<=a)+.*"); 

không có kết quả ...

bbbb Những gì tôi đang mong đợi được.

+0

Kết quả exptected của bạn là gì? – splash

Trả lời

6

Bạn đang tìm kiếm một nhóm chụp lặp đi lặp lại?

(.)\1* 

Điều này sẽ trả lại hai kết quả phù hợp.

Given:

aaabbbb 

này sẽ cho kết quả:

aaa 
bbbb 

này:

(?<=(.))(?!\1).* 

Sử dụng chủ yếu trên, đầu tiên kiểm tra rằng việc tìm kiếm nhân vật trước đó, bắt nó vào một tham chiếu trở lại, và sau đó khẳng định rằng ký tự đó không phải là ký tự tiếp theo.

Đó phù hợp:

bbbb 
+0

Tôi cần nhóm lookbehind để phù hợp với tất cả các ký tự. Tức là, trận đấu thực sự là bbbb, vì nhóm lặp lại nên bị bỏ qua. – luvieere

+0

@luvieere: Tôi đã thực hiện thay đổi đó. –

1

Lý do khiến người bỏ qua bỏ qua "a" là vì nó đang tiêu thụ "a" đầu tiên (nhưng không bắt được nó), sau đó nó chiếm phần còn lại.

Mẫu này có phù hợp với bạn không? Mẫu mới: \ba+(.+)\b Nó sử dụng một ranh giới từ \b để neo hai đầu của từ đó. Nó khớp với ít nhất một "a", tiếp theo là phần còn lại của các ký tự cho đến khi ranh giới từ kết thúc. Các ký tự còn lại được chụp trong một nhóm để bạn có thể dễ dàng tham khảo chúng.

string pattern = @"\ba+(.+)\b"; 

foreach (Match m in Regex.Matches("aaabbbb", pattern)) 
{ 
    Console.WriteLine("Match: " + m.Value); 
    Console.WriteLine("Group capture: " + m.Groups[1].Value); 
} 

UPDATE: Nếu bạn muốn bỏ qua sự xuất hiện đầu tiên của bất kỳ chữ nhân đôi, sau đó kết hợp với phần còn lại của chuỗi, bạn có thể làm điều này:

string pattern = @"\b(.)(\1)*(?<Content>.+)\b"; 

foreach (Match m in Regex.Matches("aaabbbb", pattern)) 
{ 
    Console.WriteLine("Match: " + m.Value); 
    Console.WriteLine("Group capture: " + m.Groups["Content"].Value); 
} 
+0

Làm điều đó mà không cần phải có 'b' hoặc 'a' trong regex của bạn. –

+0

@John cảm ơn tôi đã được gắn cố định vào chữ "a" cụ thể. Mẫu thứ 2 của tôi hoạt động với bất kỳ ký tự trùng lặp nào và không mã hóa nó. –

+0

Được rồi, +1, tôi cho rằng tôi ngắn gọn hơn một chút, nhưng có vẻ như điều này dễ đọc hơn. –

3

I figured it out cuối cùng:

Regex expression = new Regex("(?<=a+)[^a]+"); 

foreach (Match result in expression.Matches(@"aaabbbb")) 
    MessageBox.Show(result.Value); 

Tôi không phải cho phép a s để tôi kết hợp bởi các tổ chức phi lookbehind. Bằng cách này, biểu thức sẽ chỉ khớp với các lần lặp lại b sau a lặp lại.

Matching aaabbbb sản lượng bbbb và phù hợp với kết quả trong aaabbbbcccbbbbaaaaaabbzzabbbbbbbcccbbbb, bbzzbbb.

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