我正在regex golf处理奖励等级,目前我处理模数问题。使用的正则表达式引擎是"theoretically ECMAScript, but browser implementations vary, often by version."我不知道我的浏览器(Firefox 34.0)运行的版本。
基本上,我们的想法是匹配表单
的表达式x* % x+ = x*
其中重复x
的数量代表数字。捕获只是匹配有效的模运算。
到目前为止,我的最佳解决方案如下:
^(?=x+ % (x+) )\1*(x*) % x+ = \2$
也就是说,我使用前瞻来获取第二组中x
的数量,尽可能多地匹配该模式,然后对剩余部分进行反向引用,其余部分必须是模式右手边。
现在,就这一点而言似乎有效,但在两种特定情况下失败(错误匹配):
xxxxx % xxxxx = xxxxx
xxxxxxxxxxxxxx % xxx = xxxxx
该特定正则表达式高尔夫实现的一个很酷的功能是它向您显示匹配的字符串部分。真正有趣的是,如果我取消行尾绑定($
),两者的匹配区域将从行的开头到下面的^
:
xxxxx % xxxxx = xxxxx
^
xxxxxxxxxxxxxx % xxx = xxxxx
^
这正如我所怀疑的那样 - 第一个吞噬整个第二个x
组,因此\2
最终为空。在第二个中,实际结果为2,因此\2
为xx
,这就是所有匹配的结果。但是当我添加锚点时,匹配会跳到该行的末尾。
我的表达适用于这些:
xxxxxxxxxxxx % xx = x
xxxxx % xxx = xxxx
其中结果也分别为0和2。
那是怎么回事?我错过了表达逻辑中的一个基本问题吗?
我弄清楚发生了什么。正则表达式引擎可以选择匹配\1
模式的FEWER次数,并且在两种情况下都允许它扩展\2
匹配,使其等于rhs。现在想弄清楚如何强迫它真正贪婪......也许是另一种前瞻性?欢迎提出建议。
答案 0 :(得分:2)
问题是$ 2可能匹配超过$ 1 x
s。
您可以通过简单的否定前瞻来解决它:(https://regex101.com/r/oY1mV7/1)
^(?=x+ % (x+) )\1*(?!\1)(x*) % x+ = \2$
OR(https://regex101.com/r/oY1mV7/2)
\b(x*)\1*(?!\1)(x+) % \1\b = \2\b
另一种没有外观的选项是使用possessive quantifier,但JavaScript中根本不支持:https://regex101.com/r/oY1mV7/3)
\b(x*)\1*+(x+) % \1\b = \2\b