> my $a="123abc456def"; 123abc456def > so $a ~~ m/ 23 && ef / False
它是假的,因为“$”中的“23”匹配“$”中的“23”子字符串,但此子字符串与连接中的“ef”不匹配.这有点违反直觉,因为它更容易解释$a ~~ m / 23& ef / as“$a匹配23和$a匹配ef”而不是“$a有一个匹配23的子字符串substring也匹配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
谢谢 !
lisprog
解决方法
暂时忽略正则表达式,用于使foo op bar和foo op baz更短的通用P6构造,提供op是纯粹的,即并行运行多个调用是可以的,是foo op bar&巴兹.
(主要语言的&运算符是一个Junction运算符.连接是具有两个关键特征的连接;一个是它们的语法简洁/简洁/清晰;另一个是它们的并行处理语义.)
将此应用于正则表达式匹配中的~~ op:
my $a="123abc456def"; say so $a ~~ / 23 / & / ef /
如上所述,上述通常是合适的.巴兹和……非常适合一行.
仍然使用联结逻辑但在操作数之间跳过中缀运算符的替代方法,并且可以更好地扩展到匹配的更大模式列表,如下所示:
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 / as“$a匹配23和ef”而不是“$a匹配23和$a匹配ef”.但当然,“$a匹配23和ef”仍然含糊不清.
对于阅读,你建议我们有交叉点,如上所述:
say so $a ~~ / 23 / & / ef /
就像&&和在一场比赛中,iofo适合用英语阅读上面的“$a匹配23和ef”,但这次是“$a匹配23和$a匹配ef”的缩写,就像你想要的那样.
与此同时,使用&&单个匹配内部对应于另一个有用的连接意义,也就是说它指的是将左边的正则表达式原子和右边的正则表达式原子匹配到同一个子串.
Iofo这是一种非常直观的方法,一旦人们意识到,然后习惯了这两种可能的连词解释.