2010-09-24 55 views
7

本着polygenelubricants'努力用正則表達式來做愚蠢的事情, 我當前嘗試讓.NET正則表達式引擎爲我乘法。與.NET正則表達式相乘

這當然沒有實用價值,而是純粹的理論練習。

到目前爲止,我已經到了這個怪物,它應該檢查1的數量乘以2的數量是否等於字符串中的3的數量。

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); 

不幸的是,它不工作,我不知道爲什麼。我評論它向你展示我認爲引擎應該做什麼,但我可能會在這裏。 輸出示例:

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

任何想法都歡迎!

回答

1

我敢肯定,這個問題是在這一行:

(?<b-c>)* 

從我可以告訴,沒有文字在那裏進行匹配,正則表達式拒絕一個以上的時間相匹配。 我瘦身的正則表達式如下:

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

其中傳遞1但未能上111。也試過(?<-a>)*。沒有不同。然而,將其更改爲

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

經過兩個12111222。因此,從""的比賽到與某事匹配導致正則表達式按預期工作。

回到你原來的正則表達式,我的猜測是(?<b-c>)*只匹配0-1次,這就解釋了爲什麼在你的字符串中有一個2有效,但有多個失敗。

使用一個字符串11也失敗,它遵循相同的邏輯,因爲這使得整個匹配"",這很可能意味着它只匹配一次,導致(?(a)(?!))失敗。

+0

尼斯分析,謝謝!我會看看我是否可以解決這個問題...... =) – Jens 2010-09-27 06:16:09

0

有了Joel的輸入,我能夠使它工作,稍微修改算法以避免那些(?<b-c>)*行。

看哪:

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); 

我想給一個ideone鏈接,但結果我到那裏與我的不同。也許是因爲我使用.NET 4.0而他們不?

+0

這在'11'情況下仍然失敗,但我還沒有發現它的另一個失敗案例。 – 2010-09-27 15:57:46