最佳正则表达式技巧是关于编写匹配r1
但不匹配的正则表达式r2
。他们给出的示例是一个匹配Tarzan
(和"Tarzan and Jane"
)但不匹配的正则表达式"Tarzan"
。在经历了一些不起作用的事情之后,他们给出了“有史以来最好的正则表达式技巧”:
"Tarzan"|(Tarzan)
理论上,这会首先匹配“坏字符串”,跳过好字符串,但不将坏字符串包含在捕获组中。如果只出现好字符串,我们最后匹配它并将其包含在捕获组中。
“最佳正则表达式技巧”的一个缺点是,即使它没有捕获它,它仍然匹配 。例如,如果没有一些额外的样板,您就不能在条件中使用它吗?"Tarzan"
这是基于 PCRE 风格的正则表达式。Raku 使用完全不同的正则表达式符号。是否有可能更简单地完成这个技巧?理想情况下,这应该是可能的:
> ('"Tarzan"', 'Tarzan', '"Tarzan and Jane"') <<~~>> /some-regex/
(Nil 「Tarzan」 「Tarzan」)
首先,Raku 中“最佳正则表达式技巧”的直接但惯用的等价物:
笔记:
«op»
元运算符构造,它可以简洁地映射多个输入的匹配。我使用它加上 Raku 的« ... »
术语引用构造来简洁地指定匹配输入。'"Tarzan"'
而不是"Tarzan"
。与旧的正则表达式方言不同,Raku 将正则表达式中的形式代码"foo"
视为表示三个字符串。表示五个字符串的foo
一种方法是写。"foo"
'"foo"'
(Tarzan)
捕获是捕获零。因此代码say
不是。.[0]
.[1]
可以说朝着正确方向迈出的一步是:
笔记:
<(...)>
明确界定顶级捕获,将其从默认顶级捕获(捕获所有匹配的内容)缩小。<()>
表示顶层捕获为空。这不合理Nil
,但根据您的需要可能就足够了。<(Tarzan)>
指定顶级捕获(与(Tarzan)
指定第一个子捕获相反)。Raku 正则表达式的原始规范包含一些尚未实现的相关功能。它们可能有一天会被实现并提供更简单的解决方案。
另请参阅@tshiono 的回答。
另请参阅reddit 上@alatennaub 的精彩回答。
正如您所提到的,Raku 使用了完全不同的正则表达式符号。请您尝试一下:
结果:
<!after \">
表示否定后发断言。<!before \">
表示否定前瞻断言。|
可能被空格包围。这够接近了吗?
或者,在我看来更清楚一点:
或者,如果你要一直使用“从匹配中提取第一个捕获”的习语,你甚至可以将
~~
and的组合定义[0]
为一个新的运算符(这里,~~[0]
但这可能有点过头了!(而且由于错误,必须在 REPL 中占一行)。
(所有这些都建立在@alatennaub 的出色 reddit 答案之上,@raiph 已经提到过。查看该答案以了解如何完全避免匹配“Tarzan”,从而避免选择第一个捕获)
和往常一样,我从@raiph 那里学到了很多东西,这个答案对他的答案进行了小小的改进,希望可以有更多的空间:
笔记:
« ... »
我个人对引用这个词有点困惑@tests
和感觉更清晰regex
~
波浪线来平衡两者的匹配"