正则表达式在哪个位置失败?

Mor*_*zov 5 ruby regex string syntax substring

我需要一个非常简单的字符串验证器,它将显示第一个符号与所需格式不对应的位置.我想使用正则表达式,但在这种情况下,我必须找到字符串停止对应表达式的地方,我找不到一个方法来做到这一点.(它必须是一个相当简单的方法......也许没有一个?)

例如,如果我有正则表达式:

/^Q+E+R+$/
Run Code Online (Sandbox Code Playgroud)

用字符串:

"QQQQEEE2ER"
Run Code Online (Sandbox Code Playgroud)

期望的结果应该是7

Cas*_*yte 5

一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组写它:

^(Q+(E+(R+($)?)?)?)?
Run Code Online (Sandbox Code Playgroud)

然后,您只需要计算获得的捕获组的数量,以了解正则表达式引擎在模式中停止的位置,并且可以确定字符串中匹配结尾与整个匹配长度的偏移量.

正如@ zx81在他的评论中注意到的那样,如果其中一个元素可以匹配下一个元素(示例Q可以匹配元素E),则事情会变得不同.

假设Q是\w(并且可以匹配E和R).对于字符串QQQEEERRR的先例模式会给只有一个捕获组(贪婪的\w+比赛全部)时,^(\w+)(E+)(R+)$将给予三组:QQQEE,E,RRR

要获得相同的结果,您需要添加一个替换:

^((?:\w+(?=E)|\w+)(E+(R+($)?)?)?)?
Run Code Online (Sandbox Code Playgroud)

在交替中,必须首先测试E存在的情况,并且仅当该分支失败(使用超前)时,才使用E不存在的另一个分支.

因此,可以像这样重写完整模式来处理这种特定情况:

^((?:Q+(?=E)|Q+)((?:E+(?=R)|E+)((?:R+(?=$)|R+)($)?)?)?)?
Run Code Online (Sandbox Code Playgroud)

也许你可以看看宝石amatch.

  • +1很好.`/ ^(Q +(E +(R +($)?)?)?)?/.match('QQQQEEE2ER')[0] .length`给出OP正在寻找的`7`.如果它返回的值等于测试字符串的长度,则匹配成功. (2认同)