简体   繁体   English

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

[英]Multiplication with .NET regular expressions

In the spirit of polygenelubricants ' efforts to do silly things with regular expressions, I currently try to get the .NET regex engine to multiplicate for me. 本着polygenelubricants努力用正则表达式做傻事的精神,我目前试图让.NET正则表达式引擎为我倍增。

This has, of course, no practical value and is meant as a purely theoretical exercise. 当然,这没有实际价值,而是纯粹的理论练习。

So far, I've arrived at this monster, that should check if the number of 1s multiplied by the number of 2s equals the number of 3s in the string. 到目前为止,我已经到了这个怪物,应该检查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);

Unfortunately, its not working, and I am at a loss why. 不幸的是,它不起作用,我不知道为什么。 I commented it to show you what I think the engine should be doing, but I may be off here. 我评论它是为了告诉你我认为引擎应该做什么,但我可能会离开这里。 Examples of output: 输出示例:

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

Any thought are welcome! 欢迎任何想法!

I'm pretty sure the problem is in this line: 我很确定问题出在这一行:

(?<b-c>)*

From what I can tell, with no text to match in there, the Regex refuses to match it more than one time. 从我所知道的,没有文字可以匹配,正则表达式拒绝匹配它不止一次。 I slimmed down the Regex to the following: 我将正则表达式简化为以下内容:

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

Which passes on 1 but fails on 111 . 传递1失败111 Also tried (?<-a>)* . 还试过(?<-a>)* No difference. 没有不同。 However, changing it to 但是,将其更改为

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

passes on both 12 and 111222 . 通过12111222 So going from a match of "" to a match with something causes the Regex to work as expected. 因此,从""匹配""到匹配某事会导致正则表达式按预期工作。

Getting back to your original Regex, my guess is that (?<bc>)* is only matching 0-1 times, which explains why having one 2 in your string works, but having more than one fails. 回到你的原始正则表达式,我的猜测是(?<bc>)*仅匹配0-1次,这解释了为什么在你的字符串中有一个2工作,但有多个失败。

Using a string of 11 also fails, which follows the same logic, as that makes the entire match "" , which most likely means it only matches once, causing (?(a)(?!)) to fail. 使用11的字符串也会失败,它遵循相同的逻辑,因为它使整个匹配"" ,这很可能意味着它只匹配一次,导致(?(a)(?!))失败。

With Joel's input I was able to get it to work, modifying the algorithm slightly to avoid those (?<bc>)* lines. 通过Joel的输入,我能够使其工作,稍微修改算法以避免那些(?<bc>)*行。

Behold: 看吧:

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

I'd like to give an ideone link, but the result I get there differs from mine. 我想给出一个ideone链接,但我得到的结果与我的不同。 Maybe because I am using .NET 4.0 and they don't? 也许是因为我使用的是.NET 4.0而他们没有?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM