我正在尝试为一个东西编写一个非常非常基本的解析器,作为其中的一部分,我决定使用正则表达式来查找正则表达式。
这是正则表达式的样子:
r/pattern/flags
除了/
可以是/|:!`.
中的任何一个。例如,您可以匹配没有大量\/
s的网址。现在,这就是我到目前为止:
r([\/|:!`.])(.*?)(?<![^\\]\\)\1x?m?i?g?a?s?
但是,这有一个问题:它与r/abcde/ai
不匹配。鉴于应该能够以任何顺序指定标志,这将失败。我也试过这个:
r([\/|:!`.])(.*?)(?<![^\\]\\)\1([xmigas]+)
但这有一个问题,它允许r|abc|aaaasxmaaaiisggss
,它不应该。如果我将其限制为[xmigas]{,6}
,我仍然可以写|iiiii
。
现在,我意识到我可以做很长很复杂的事情,但这不可能扩展,所以我宁愿避免它。有没有办法匹配一组最多可以出现一次,任何顺序,没有任何复杂的字符?
在这种特殊情况下,我使用Ruby,如果有必要,我可以添加宝石。我也许能够切换语言,虽然它需要做很多工作而且我更不愿意。
这是一个个人项目,旨在为了好玩。请忽略使用正则表达式搜索正则表达式的想法有多糟糕。
答案 0 :(得分:2)
Negative lookahead应该做你想做的事。为简单起见,我将忽略除标志匹配部分之外的所有内容。
请考虑以下事项:
(?:([xmigas])(?!.*\1.*))*
我们寻找有效的旗号,但我们断言此旗帜字母后面的内容不再包含相同的旗帜字母。然后我们重复整个事情0次或更多次(让前瞻隐含地防止存在任何额外的标志)。
答案 1 :(得分:0)
这匹配x,m,i,g,a,s的所有组合,没有重复:
^(?:([xmigas])(?!.*\1))*$
特别是在你的情况下,表达式将是
/^r([\/|:!`.])(.*?)\1(?:([xmigas])(?!.*\3))*$/
在行动here
中查看另外,请参阅@ Chris的答案了解详情