2010-09-24 37 views
7

Theo tinh thần của polygenelubricants 'nỗ lực để làm những điều ngớ ngẩn với cụm từ thông dụng, Tôi hiện đang cố gắng lấy công cụ .NET regex để nhân cho tôi.Phép nhân với các biểu thức chính quy .NET

Điều này có, tất nhiên, không có giá trị thực tiễn và có nghĩa là một bài tập hoàn toàn lý thuyết.

Cho đến nay, tôi đã đến con quái vật này, nên kiểm tra xem số lượng 1s nhân với số 2 bằng bằng số 3 trong chuỗi.

Regex regex = new Regex(
@" 
^ 
(1(?<a>))* # increment a for each 1 
(2(?<b>))* # increment b for each 2 
    (?(a) # if a > 0 
     (     
      (?<-a>)    # decrement a 
      (3(?<c-b>))*  # match 3's, decrementing b and incrementing c until 
           # there are no 3's left or b is zero 
      (?(b)(?!))   # if b != 0, fail 
      (?<b-c>)*   # b = c, c = 0 
     ) 
    )*  # repeat 
(?(a)(?!)) # if a != 0, fail 
(?(c)(?!)) # if c != 0, fail 
$ 
", RegexOptions.IgnorePatternWhitespace); 

Thật không may, nó không hoạt động và tôi không biết tại sao. Tôi nhận xét nó để cho bạn thấy những gì tôi nghĩ rằng động cơ nên làm, nhưng tôi có thể ra khỏi đây. Ví dụ về đầu ra:

regex.IsMatch("123") // true, correct 
regex.IsMatch("22") // true, correct 
regex.IsMatch("12233") // false, incorrect 
regex.IsMatch("11233"); // true, correct 

Mọi ý tưởng đều được hoan nghênh!

Trả lời

1

Tôi chắc rằng vấn đề là ở dòng này:

(?<b-c>)* 

Từ những gì tôi có thể nói, không có văn bản để phù hợp trong đó, các Regex từ chối để phù hợp với nó nhiều hơn một lần. Tôi rút gọn xuống Regex như sau:

(1(?<a>))* 
(?(a)(?<-a>))* 
(?(a)(?!)) 

nào đi trên 1 nhưng không thành công trên 111. Cũng đã thử (?<-a>)*. Không khác nhau. Tuy nhiên, thay đổi nó thành

(1(?<a>))* 
(?(a)((?<-a>)(2(?<b>))(?<-b>)))* 
(?(a)(?!)) 

chuyển trên cả hai 12111222. Vì vậy, đi từ một trận đấu của "" để phù hợp với một cái gì đó khiến cho Regex hoạt động như mong đợi.

Quay lại Regex ban đầu của bạn, tôi đoán rằng (?<b-c>)* chỉ phù hợp với 0-1 lần, điều này giải thích tại sao có một chuỗi 2 trong chuỗi hoạt động nhưng có nhiều lỗi.

Sử dụng chuỗi 11 cũng không thành công, theo cùng logic, vì điều đó làm cho toàn bộ kết quả phù hợp "", nhiều khả năng chỉ khớp với một lần, gây ra (?(a)(?!)).

+0

Phân tích tốt, cảm ơn! Tôi sẽ xem nếu tôi có thể sửa chữa điều đó ... =) – Jens

0

Với đầu vào của Joel, tôi có thể làm cho nó hoạt động, sửa đổi thuật toán một chút để tránh những dòng (?<b-c>)* đó.

Kìa:

Regex regex = new Regex(
@" 
^ 
(1(?<a>))* # increment a for each 1 
(2(?<b>))* # increment b for each 2 
    (?(a) # if a > 0 
     (
      (?<-a>)    # decrement a 
      (?(b)    # if b > 0 
       (          
        (3(?<c-b>))*  # match 3's, decrementing b and incrementing c until 
             # there are no 3's left or b is zero 
        (?(b)(?!))   # if b != 0, fail 
       ) 
       |      # else (b = 0) 
       (
        (3(?<b-c>))*  # match 3's, decrementing c and incrementing b until 
             # there are no 3's left or c is zero 
        (?(c)(?!))   # if c != 0, fail 
       ) 
      ) 
     ) 
    )*  # repeat 
(?(a)(?!)) # if a != 0, fail 
$ 
", RegexOptions.IgnorePatternWhitespace); 

Tôi muốn đưa ra một liên kết ideone, nhưng kết quả tôi đạt được điều đó khác với tôi. Có lẽ vì tôi đang sử dụng .NET 4.0 và họ không?

+0

Điều này vẫn không thành công trên trường hợp '11', nhưng tôi đã không tìm thấy một trường hợp lỗi khác cho nó. –

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