可以做一个join,使字符串匹配两个或多个regex模式。
> "banana" ~~ m:g/ . a && b . /
(?ba?)
Run Code Online (Sandbox Code Playgroud)
另外,可以否定一个字符类别:如果我只想匹配辅音,我可以采用所有字母并减去元音的字符类别:
> "camelia" ~~ m:g/ <.alpha> && <-[aeiou]> /
(?c? ?m? ?l?)
Run Code Online (Sandbox Code Playgroud)
但是,如果我需要否定/减去某个字符regex长度,而不是一个字符类别,该怎么办?像这样:
> "banana" ~~ m:g/ . **3 && NOT ban / # doesn't work
(?ana?)
Run Code Online (Sandbox Code Playgroud)
TL; DR Moritz的答案涵盖了一些重要问题。该答案集中于根据Eugene的注释匹配子字符串(“我想找到与regex匹配R但与regex不匹配的子字符串A”。)。
写,说你是不是坐在马上断言之前,正则表达式,你不希望匹配,然后按照与正则表达式,你也想匹配:
say "banana" ~~ m:g/ <!before ban> . ** 3 / # (?ana?)
Run Code Online (Sandbox Code Playgroud)
该before断言称为“零宽度”断言。这意味着,如果它成功(在这种情况下,意味着它不能 “投其所好”,因为我们已经写了!before,而不是仅仅before),则匹配位置不会移动。
(当然,如果这样的断言失败,并且在当前的匹配位置没有匹配的替代模式,那么匹配引擎会向前移动一个字符位置。)
正如您在问题中所显示的,您可能希望模式相反,先是正匹配,然后是负匹配。(也许正匹配比负匹配快,所以颠倒顺序将加快匹配速度。)
适用于相当简单的模式的一种方法是在断言后使用否定:
say "banana" ~~ m:g/ . ** 3 <!after ban> / # (?ana?)
Run Code Online (Sandbox Code Playgroud)
但是,如果负模式足够复杂,则可能需要使用以下公式:
say "banana" ~~ m:g/ . ** 3 && <!before ban> .*? / # (?ana?)
Run Code Online (Sandbox Code Playgroud)
这将插入一个&&正则表达式联合运算符,假定LHS模式成功,则在重置匹配位置后也会尝试RHS (这就是RHS现在以<!before ban>而不是开始的原因<!after ban>),并要求RHS匹配相同长度的输入(即为什么在<!before ban>后面加上.*?“填充”)。
“否定”正则表达式是什么意思?
当您谈论正则表达式的计算机科学定义时,它总是需要匹配整个字符串。在这种情况下,否定很容易定义。但默认情况下,Perl 6 中的正则表达式搜索,因此它们不必匹配整个字符串。这意味着您必须小心定义“否定”的含义。
如果通过正则表达式的否定,A您的意思是只要不匹配整个字符串就匹配的正则表达式A,反之亦然,您确实可以使用<!before ...>,但您需要小心锚定:/ ^ <!before A $ > .* /这是否是精确的否定。
如果通过否定正则表达式A您的意思是“仅A在字符串中没有匹配的情况下匹配”,则必须使用类似/ ^ [<!before A> .]* $ /.
如果您对否定有其他定义,请分享。
| 归档时间: |
|
| 查看次数: |
213 次 |
| 最近记录: |