ruby – 用于查找最多n个连续模式的正则表达式
让我们说我们的模式是大写字母的正则表达式(但我们可能有比搜索大写更复杂的模式)
要找到至少n个连续模式(在这种情况下,我们正在寻找的模式只是一个大写字母),我们可以这样做: (使用Ruby) 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,尽管我们可以leave it as it is),以便将其写为正则表达式.如果我们将我们的模式看作接收’1’并且没有接收到接收’0’的模式,我们可以绘制一个简单的DFA图(其中n = 1,我们最多想要一个模式): 具体来说,我想知道这是如何成为一个正则表达式.一般来说,我希望找到如何用正则表达式找到“最多”,因为我的正则表达式技能感到特别“至少”单独发痒. 旅行危险 – 在精神上不是正确的解决方案 请注意,这个问题不是this post的重复,因为使用公认的方法会给出: 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"] (感谢Rubber Duck) 但我仍然想知道如何仅使用正则表达式找到最多n次出现. (知识!) 解决方法
为什么你的尝试不起作用
您当前的尝试存在一些问题. > X是匹配的一部分的原因是.*是贪婪的并且尽可能地消耗 – 因此,只留下所需的两个大写字母与尾随位匹配.这可以用非贪婪的量词来修复. 用当前的方法解决所有这些问题很难(我尝试过并且失败了 – 如果你想看到我的尝试,请检查这篇文章的编辑历史,直到我决定完全废弃这种方法).所以让我们试试别的! 寻找另一种解决方案 我们想要匹配的是什么?忽略边缘情况,匹配从字符串的开头开始或在字符串的结尾处结束,我们希望匹配:
这是Jeffrey Friedl的unrolling-the-loop的理想选择.看起来像 [^A-Z]+(?:[A-Z][^A-Z]+)* 现在边缘情况怎么样?我们可以这样说出来: >我们希望在比赛开始时允许一个大写字母,只要它在字符串的开头. 要将这些添加到我们的模式中,我们只需将大写字母与适当的锚分组,并将它们标记为可选: (?:^[A-Z])?[^A-Z]+(?:[A-Z][^A-Z]+)*(?:[A-Z]$)? Now it’s really working.更好的是,我们不再需要捕捉了! 推广解决方案 通过将每个[A-Z]改变为[A-Z] {1,n},从而允许最多n个大写字母到目前为止只允许一个大写字母,这个解决方案很容易推广到“最多n个连续大写字母”的情况. See the demo for (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |