gpt4 book ai didi

javascript - 找出正则表达式失败的位置

转载 作者:可可西里 更新时间:2023-11-01 01:57:52 25 4
gpt4 key购买 nike

我正在尝试用 JavaScript 编写一个词法分析器来查找简单的特定领域语言的标记。我从一个简单的实现开始,它只是尝试匹配一行中当前位置的后续正则表达式,以确定它是否匹配某种标记格式并接受它。

问题是,当这样的正则表达式中的某些内容不匹配时,整个正则表达式都会失败,所以我不知道究竟是哪个字符导致它失败。

有没有办法找出导致正则表达式失败的字符串中的位置?

INB4:我不是在询问调试我的正则表达式并验证其正确性。它已经是正确的,匹配正确的字符串并丢弃不正确的字符串。我只想以编程方式知道正则表达式停止匹配的确切位置,找出用户输入中不正确的字符的位置,以及其中有多少是好的。

有没有办法只用简单的正则表达式而不是继续实现一个成熟的有限状态自动机?

最佳答案

简答

There is no such thing as a "position in the string that causes the regular expression to fail".



但是,我将向您展示一种回答相反问题的方法:

At which token in the regex did the engine become unable to match the string?



讨论

在我看来, the position in the string which caused the regular expression to fail 的问题是颠倒的。当引擎用左手向下移动字符串并用右手向下移动模式时,一个匹配六个字符的正则表达式标记可以稍后,由于量词和回溯,在下一个匹配零个字符 - 或扩展以匹配十。

在我看来,一个更合适的问题是:

At which token in the regex did the engine become unable to match the string?



例如,考虑正则表达式 ^\w+\d+$和字符串 abc132z .
\w+实际上可以匹配整个字符串。然而,整个正则表达式都失败了。说正则表达式在字符串末尾失败是否有意义?我不这么认为。考虑一下。

最初, \w+将匹配 abc132z .然后引擎前进到下一个 token : \d+ .在这个阶段,引擎在字符串中回溯,逐渐让 \w+放弃 2z (因此 \w+ 现在只对应于 abc13 ),允许 \d+匹配 2 .

在这个阶段, $断言失败,因为 z离开了。引擎回溯,让 \w+ ,放弃 3字符,然后是 1 (因此 \w+ 现在只对应于 abc ),最终允许 \d+匹配 132 .在每一步,引擎都会尝试 $断言和失败。根据引擎内部结构,可能会发生更多回溯: \d+将再次放弃 2 和 3,然后 \w+将放弃c和b。当引擎最终放弃时, \w+仅匹配初始 a .你能说正则表达式“在“3”上失败了吗?在“b”上?

不。如果您从左到右查看正则表达式模式,您可以争辩说它在 $ 上失败了。 ,因为它是我们无法添加到匹配中的第一个标记。请记住,还有其他方法可以证明这一点。

下,我会给你一个截图来形象化这一点。但首先,让我们看看我们是否可以回答另一个问题。

其他问题

是否有技术可以让我们回答另一个问题:

At which token in the regex did the engine become unable to match the string?



这取决于您的正则表达式。如果您能够将您的正则表达式分割成干净的组件,那么您可以在捕获组内设计一个带有一系列可选前瞻的表达式,从而使匹配始终成功。第一个未设置的捕获组是导致失败的组。

Javascript 在可选的前瞻方面有点吝啬,但你可以这样写:
^(?:(?=(\w+)))?(?:(?=(\w+\d+)))?(?:(?=(\w+\d+$)))?.

在 PCRE、.NET、Python... 中,您可以更紧凑地编写:
^(?=(\w+))?(?=(\w+\d+))?(?=(\w+\d+$))?.

这里会发生什么?每个前瞻都以最后一个前瞻为基础,一次添加一个 token 。因此我们可以分别测试每个 token 。最后的点是视觉反馈的可选花样:我们可以在调试器中看到至少匹配一个字符,但我们不关心那个字符,我们只关心捕获组。
  • 第 1 组测试 \w+ token
  • 第 2 组似乎在测试 \w+\d+ ,因此,它会逐步测试 \d+ token
  • 第 3 组似乎在测试 \w+\d+$ ,因此,它会逐步测试 $ token

  • 共有三个捕获组。如果这三个都设置好了,那么比赛就完全成功了。如果仅未设置第 3 组(如 abc123a ),您可以说 $导致失败。如果设置了组 1 但未设置组 2(如 abc ),您可以说 \d+导致失败。

    供引用:故障路径的内部 View

    值得一提的是,这里是 RegexBuddy 调试器的故障路径 View 。

    RegexBuddy Debug

    关于javascript - 找出正则表达式失败的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23839481/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com