假设我们的模式是大写字母的正则表达式(但我们可以有一个比搜索大写字母更复杂的模式)
要找到至少n 个连续的模式(在这种情况下,我们正在寻找的模式只是一个大写字母),我们可以这样做:
(使用红宝石)
somestring = "ABC deFgHij kLmN pQrS XYZ abcdEf"
at_least_2_capitals = somestring.scan(/[A-Z][A-Z]+/)
=> ["ABC", "XYZ"]
at_least_3_capitals = somestring.scan(/[A-Z]{3}[A-Z]*/)
=> ["ABC", "XYZ"]
但是,我如何搜索最多n 个连续的模式,例如,最多一个连续的大写字母:
matches = somestring.scan(/ ??? /)
=> [" deFgHij kLmN pQrS ", " abcdEf"]
详细策略
我读到我需要否定“至少”正则表达式,将其转换为 DFA,否定接受状态,(然后将其转换回 NFA,尽管我们可以保持原样)所以将其写为正则表达式. 如果我们认为遇到我们的模式时接收到“1”,而没有接收到模式时接收到“0”,我们可以绘制一个简单的 DFA 图(其中 n=1,我们最多需要一个模式):
具体来说,我想知道这如何成为一个正则表达式。一般来说,我希望找到如何用正则表达式找到“至多”,因为我的正则表达式技能只用“至少”就会受到阻碍。
绊倒危险 - 精神上不太正确的解决方案
请注意,这个问题不是这篇文章的重复,因为使用那里公认的方法会给出:
somestring.scan(/[A-Z]{2}[A-Z]*(.*)[A-Z]{2}[A-Z]*/)
=> [[" deFgHij kLmN pQrS X"]]
这不是 DFA 所显示的,不仅仅是因为它错过了第二次寻找的匹配 - 更重要的是它包含了不应该的“X”,因为“X”后面跟着另一个大写字母,从 DFA 中我们看到一个大写后面跟着另一个大写不是一个接受状态。
你可以建议
somestring.split(/[A-Z]{2}[A-Z]*/)
=> ["", " deFgHij kLmN pQrS ", " abcdEf"]
(感谢橡皮鸭)
但我仍然想知道如何仅使用正则表达式找到最多 n 次出现。(求知识!)