本着polygenelubricants努力用正则表达式做傻事的精神, 我目前试图让.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
欢迎任何想法!
答案 0 :(得分:1)
我很确定问题出在这一行:
(?<b-c>)*
据我所知,由于没有文字匹配,正则表达式拒绝多次匹配。 我将正则表达式简化为以下内容:
(1(?<a>))*
(?(a)(?<-a>))*
(?(a)(?!))
哪个传递到1
但在111
上失败。还尝试了(?<-a>)*
。没有不同。但是,将其更改为
(1(?<a>))*
(?(a)((?<-a>)(2(?<b>))(?<-b>)))*
(?(a)(?!))
传递12
和111222
。因此,从""
的匹配到匹配的东西会导致正则表达式按预期工作。
回到原来的正则表达式,我的猜测是(?<b-c>)*
只匹配0-1次,这就解释了为什么在你的字符串中有一个2,但有多个失败。
使用11
的字符串也会失败,它遵循相同的逻辑,因为整个匹配""
,这很可能意味着它只匹配一次,导致(?(a)(?!))
失败
答案 1 :(得分: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而他们没有?