2015-02-28 16 views
13

Sau nhiều giờ tìm kiếm, tôi quyết định đặt câu hỏi này. Tại sao cụm từ thông dụng này: ^(dog).+?(cat)? không hoạt động như tôi nghĩ nó nên hoạt động (bắt con chó và mèo đầu tiên nếu có)? Tôi đang thiếu gì ở đây?Regex nhóm chụp tùy chọn?

dog, cat 
dog, dog, cat 
dog, dog, dog 

Trả lời

17

Lý do mà bạn không nhận được một tùy chọn cat sau một miễn cưỡng có trình độ .+? là nó là cả hai tùy chọn và không neo: động cơ không buộc phải làm cho trận đấu đó, bởi vì nó có thể điều trị một cách hợp pháp cat là "đuôi" của chuỗi .+?.

Nếu yo neo mèo ở phần cuối của chuỗi, tức là sử dụng ^(dog).+?(cat)?$, bạn sẽ nhận được một trận đấu, mặc dù:

Pattern p = Pattern.compile("^(dog).+?(cat)?$"); 
for (String s : new String[] {"dog, cat", "dog, dog, cat", "dog, dog, dog"}) { 
    Matcher m = p.matcher(s); 
    if (m.find()) { 
     System.out.println(m.group(1)+" "+m.group(2)); 
    } 
} 

in này (demo 1)

dog cat 
dog cat 
dog null 

Đỗ bạn xảy ra để biết làm thế nào để đối phó với nó trong trường hợp có cái gì đó sau khi con mèo?

Bạn có thể đối phó với nó bằng cách xây dựng một biểu thức phức tạp hơn phù hợp với bất cứ điều gì ngoại trừ cat, như thế này:

^(dog)(?:[^c]|c[^a]|ca[^t])+(cat)? 

Bây giờ cat có thể xảy ra bất cứ nơi nào trong chuỗi mà không có một neo (demo 2).

+3

Cảm ơn. Bạn có biết làm thế nào để đối phó với nó trong trường hợp có cái gì đó sau khi con mèo? Ví dụ: "chó, chó, mèo, blah'. Tôi chỉ muốn bắt con chó đầu tiên và mèo tùy chọn (có thể có tối đa một con mèo). – forsajt

+1

rất muốn xem câu trả lời này –

4

@ câu trả lời dasblinkenlight là tuyệt vời, nhưng đây là một regexp để cải thiện phần 2 của nó, khi ông/cô ấy hỏi

Bạn có xảy ra cho biết làm thế nào để đối phó với nó trong trường hợp có điều gì đó sau khi con mèo?

Regexp ^(dog)(.+(cat))? sẽ yêu cầu bạn chụp nhóm không. 3 thay vì 2 để có được con mèo tùy chọn, nhưng chỉ hoạt động tốt mà không có thủ đoạn char-by-char.

Và đây là the demo (trong đó, một lần nữa, được chia hai từ bản demo @ dasblinkenlight của mà cho phép tôi để tinker và tìm giải pháp này, nhờ một lần nữa!)

+0

Cũng hoạt động với nhóm không chụp như^(dog) (?:. + (Cat))? do đó bạn không có thêm nhóm chụp trong đó –

2

@ mở rộng figha có thể được kéo dài hơi hơn nữa vẫn còn, để không làm cho chụp thứ hai không cần thiết.

Sử dụng ?: để làm cho phần được đánh dấu của một regex không thể bắt được. Vì vậy, regex sẽ trở thành: ^(dog)(?:.+(cat))?

Một lần nữa, đây là extended demoregex test.

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