.NET 正则表达式的乘法
本着 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
欢迎任何想法!
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.
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.
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我很确定问题出在这一行:
据我所知,由于其中没有可匹配的文本,正则表达式拒绝多次匹配它。
我将正则表达式精简为以下内容:
它在
1
上通过,但在111
上失败。还尝试了(?<-a>)*
。没有区别。但是,将其更改为同时传递
12
和111222
。因此,从""
匹配到与某些内容匹配会导致正则表达式按预期工作。回到原来的正则表达式,我的猜测是
(?)*
仅匹配 0-1 次,这解释了为什么字符串中有一个 2 有效,但有多个 2失败。使用
11
字符串也会失败,这遵循相同的逻辑,因为这会导致整个匹配""
,这很可能意味着它只匹配一次,导致(?(a)(?!))
失败。I'm pretty sure the problem is in this line:
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:
Which passes on
1
but fails on111
. Also tried(?<-a>)*
. No difference. However, changing it topasses on both
12
and111222
. 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
(?<b-c>)*
is only matching 0-1 times, which explains why having one 2 in your string works, but having more than one fails.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.根据 Joel 的输入,我能够让它工作,稍微修改算法以避免那些
(?)*
行。看哪:
我想提供一个 ideone 链接,但我得到的结果与我的不同。也许是因为我正在使用 .NET 4.0 而他们没有?
With Joel's input I was able to get it to work, modifying the algorithm slightly to avoid those
(?<b-c>)*
lines.Behold:
I'd like to give an ideone link, but the result I get there differs from mine. Maybe because I am using .NET 4.0 and they don't?