使用.NET正则表达式进行乘法运算

Jen*_*ens 7 .net c# regex theory

本着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);
Run Code Online (Sandbox Code Playgroud)

不幸的是,它不起作用,我不知道为什么.我评论它是为了告诉你我认为引擎应该做什么,但我可能会离开这里.输出示例:

regex.IsMatch("123") // true, correct
regex.IsMatch("22") // true, correct
regex.IsMatch("12233") // false, incorrect
regex.IsMatch("11233"); // true, correct
Run Code Online (Sandbox Code Playgroud)

欢迎任何想法!

Joe*_*eau 1

我很确定问题出在这一行:

(?<b-c>)*
Run Code Online (Sandbox Code Playgroud)

据我所知,由于其中没有可匹配的文本,正则表达式拒绝多次匹配它。我将正则表达式精简为以下内容:

(1(?<a>))*
(?(a)(?<-a>))*
(?(a)(?!))
Run Code Online (Sandbox Code Playgroud)

哪个通过1但失败111。也尝试过(?<-a>)*。没有不同。但是,将其更改为

(1(?<a>))*
(?(a)((?<-a>)(2(?<b>))(?<-b>)))*
(?(a)(?!))
Run Code Online (Sandbox Code Playgroud)

传递12111222。因此,从 的 匹配""到 与某物的匹配 会导致正则表达式按预期工作。

回到原来的正则表达式,我的猜测是(?<b-c>)*只匹配 0-1 次,这解释了为什么字符串中只有 1 个 2 有效,但超过 1 个就会失败。

使用字符串11也会失败,这遵循相同的逻辑,因为这会导致整个 match "",这很可能意味着它只匹配一次,从而导致(?(a)(?!))失败。