Perl6正则表达式匹配连词&&如果连词中的所有部分都匹配相同的子字符串而不是整个字符串,则返回True:
> my $a="123abc456def";
123abc456def
> so $a ~~ m/ 23 && ef /
False
这是False,因为连接词中的“23”与$ a中的“23”子字符串匹配,但是此子字符串与连接词中的“ef”不匹配。这有点违反直觉,因为将$ a ~~ m/23 && ef/解释为“$ a匹配23而$ a匹配ef”比“$ a具有匹配23的子字符串并且此子字符串也匹配ef”更容易理解。 ”。
如果我有n个正则表达式,并且我想查看所有这n个正则表达式是否都匹配相同的整个字符串,而不是匹配整个字符串的相同子字符串部分,那么编写perl6表达式的最佳方法是什么?
在这个例子中,我真的想做
so (($a ~~ /23/) && ($a ~~ /ef/))
如果正则表达式的数量很大,则除了使用循环外,上面的代码很难编写:
so (gather {for @myRegexes { take $a ~~ / $_ /; } }).all
有没有更简单的方法?
通过交替,将其读为“$ a匹配23或$ a匹配ef”比“$ a匹配23或ef的部分”要容易得多:
> so $a ~~ m/ 23 || ef /
True
谢谢 !
赖脯
最佳答案
专注于简单性而非速度的解决方案
暂时忽略正则表达式,使foo op bar and foo op baz
变得更短的通用P6构造是op
,前提是foo op bar & baz
是纯的(可以并行运行多个调用即可)。
(主要语言的&
运算符是Junction运算符。连接点是具有两个关键特征的连接;一个是其语法简洁/简单/清晰;另一个是其并行处理语义。)
将其应用于正则表达式匹配项中的~~
op:
my $a="123abc456def";
say so $a ~~ / 23 / & / ef /
如果
bar & baz & ...
非常适合单行,则上面的代码通常是合适的。仍然使用结点逻辑,但跳过操作数之间的中缀运算符,并更好地缩放到更大的模式列表以进行匹配的替代方法是这样的:
my @keywords = <12 de>;
say so all ( $a.match: / $_ / for @keywords ) ;
(感谢@lisprogtor在我的原始代码中为此发现并耐心地解释了该错误。)
专注于速度而非简单性的解决方案
有许多方法可以优化速度。我只提供一个。
如果您的所有或大多数模式只是字符串而不是正则表达式,则对字符串使用the
.contains
method而不是正则表达式:say so all ( $a.contains: $_ for <23 ef> ) ;
直觉性
it is easier to interpret
$a~~m/23&&ef/
as "$a matches 23 and $a matches ef"
是的,没有。
是的,从某种意义上说,“匹配a和b”是不明确的;并且,对于任何探索正则表达式的人来说,您的猜测都是几种合理的猜测之一;特别是,您的猜测显然是您当前发现的最合适的别名,即“最简单的”。
不,如果我们的iofo可以匹配的话。
(我刚刚发明了“iofo”。我用它来表示“在我们的友好意见中”,这是ioho的一种版本,不仅真诚地谦卑,而且张开双臂,使我/我们想像有一天会成为一种看法)被一些读者愉快地分享。)
Iofo我们发现将
$a~~m/23&&ef/
读为“$ a匹配23和ef”比“$ a匹配23和$ a匹配ef”更容易。但是,当然,“$ a匹配23和ef”仍然是模棱两可的。对于阅读,您建议我们有连接点,如上所述:
say so $a ~~ / 23 / & / ef /
就像在单个匹配项中使用
&&
一样,iofo适本地以英语将上面的内容读为“$ a match 23 and ef”,但这一次是“$ a match 23和$ a match ef”的缩写,就像您想要的那样。同时,在单个匹配项中使用
&&
对应于其他有用的联合含义,也就是说,它是指将左侧的regex原子和右侧的regex原子与同一子字符串进行匹配。一旦知道并习惯了连接的这两种可能的解释,这便是一种非常直观的方法。
关于regex - perl6正则表达式匹配连词&&,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51230072/