当前位置: 首页 > 知识库问答 >
问题:

perl6正则表达式匹配连词

姚航
2023-03-14

Perl6正则表达式匹配连接

> my $a="123abc456def";
123abc456def
> so $a ~~ m/ 23 && ef /
False

它为False,因为连词中的“23”与$a中的“23”子字符串匹配,但此子字符串与连词中的“ef”不匹配。这有点违反直觉,因为它更容易解释$a ~~ m/23

如果我有n个正则表达式,我想看看是否所有这些n个正则表达式都匹配相同的整个字符串,而不是匹配整个字符串的相同子字符串部分,那么编写perl6表达式的最佳方法是什么?

在例子中,我真的想做

so (($a ~~ /23/) && ($a ~~ /ef/))

如果正则表达式的数量很大,则上述内容很难写入,除非使用循环:

so (gather {for @myRegexes { take $a ~~ / $_ /; } }).all

有没有更简单的方法?

有了替代选项,更容易理解为“$a匹配23或$a匹配ef”,而不是“匹配23或ef的$a部分”:

> so $a ~~ m/ 23 || ef /
True

谢谢

lisprog公司

共有3个答案

阴焱
2023-03-14

如果$a字符串很长,可以通过避免从每个子字符串的字符串开头重新启动来减少运行时间:

my $a="123abc456def23";
my %pats = <23 ef>.map({ $_ => 1 });
my $join = %pats.keys.join('|');
my $rx = rx{ <{$join}> };
for $a ~~ m:g/ $rx / -> $match {
    %pats{$match.Str}:delete;
    if %pats.keys.elems == 0 {
        say "Match!";
        last;
    }
}

当然,这并不会使代码更短(从更优雅的意义上说),但可以减少运行时间。

花永昌
2023-03-14

暂时忽略正则表达式,用于使foo op bar和foo op baz更短的通用P6构造,前提是op是纯粹的,因为可以并行运行对它的多个调用,是foo op bar

(主语言<代码>

将其应用于正则表达式匹配中的运算:

my $a="123abc456def";
say so $a ~~ / 23 / & / ef /

以上内容通常适用于提供条的情况

另一种仍然使用连接逻辑,但跳过操作数之间的中缀运算符,并更好地扩展到更大的模式列表以进行匹配的方法如下:

my @keywords = <12 de>;
say so all ( $a.match: / $_ / for @keywords ) ;

(感谢@lisprotor发现并耐心解释了我原始代码中的错误。)

有很多方法可以优化速度。我只提供一个。

如果所有或大部分模式都是字符串而不是正则表达式,那么请使用。包含字符串的方法而不是正则表达式:

say so all ( $a.contains: $_ for <23 ef> ) ;

更容易理解$$a ~~ m/23

是和不是。

是的,在某种意义上,“匹配a和b”有歧义;你的猜测对任何研究正则表达式的人来说都是合理的;特别是,你的猜测显然是你目前认为最合适的,也就是“最简单的”。

不,如果我们的iofo匹配的话。

(我刚刚发明了“iofo”。我用它来表示“在我们的友好意见中”,这是ioho的一个版本,不仅真诚地谦卑地表达,而且张开双臂,召唤出一种我/我们想象有一天可能会被一些读者愉快地分享的观点。)

Iofo我们发现它更容易阅读$a~~m/23

对于您建议的阅读,我们有交叉点,如上所述:

say so $a ~~ / 23 / & / ef /

与<代码>

同时,使用<代码>

Iofo这是一种非常直观的方法,一旦人们意识到并习惯了连词的这两种可能的解释。

吕皓
2023-03-14

您可以使用两个正则表达式的Junction以仅提及$a一次。

my $a = 'abcdef12345'; say so $a ~~ /23/ & /ef/   # True
my $a = 'abcde12345'; say so $a ~~ /23/ & /ef/    # False 
my $a = 'abcdef1245'; say so $a ~~ /23/ & /ef/    # False

要从正则表达式数组中形成连接,请调用。阵列上的所有。

如果只需查找文本字符串,那么包含的可能会运行得更快一些:

my $a = 'abcdef12345'; say so $a.contains(all('23', 'ef'))   # True
my $a = 'abcde12345'; say so $a.contains(all('23', 'ef'))    # False
my $a = 'abcdef1245'; say so $a.contains(all('23', 'ef'))    # False

 类似资料:
  • 我们得到了一些这样的内容:

  • 有没有人试图描述与正则表达式匹配的正则表达式? 由于重复的关键字,这个主题几乎不可能在网上找到。 它可能在实际应用程序中不可用,因为支持正则表达式的语言通常具有解析它们的方法,我们可以将其用于验证,以及一种在代码中分隔正则表达式的方法,可用于搜索目的。 但是我仍然想知道匹配所有正则表达式的正则表达式是什么样子的。应该可以写一个。

  • 主要内容:基本模式匹配,字符簇,确定重复出现基本模式匹配 一切从最基本的开始。模式,是正则表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如: 这个模式包含一个特殊的字符 ^,表示该模式只匹配那些以 once 开头的字符串。例如该模式与字符串 "once upon a time" 匹配,与 "There once was

  • 问题内容: 当字符串以数字开头时,我需要匹配,然后是一个点,然后是一个空格和1个或多个大写字符。匹配必须发生在字符串的开头。我有以下字符串。 我尝试过的正则表达式是: 它不匹配。一个有效的正则表达式将对这个问题有什么作用? 问题答案: (对不起,我先前的错误。大脑现在坚定地投入了。嗯,也许。) 这有效: 分解: =字符串开头 =一个或多个数字 (之所以转义,是因为它在字符串中,因此) =文字(或者

  • 问题内容: 我从以下格式的文件中获取输入: 现在,我想在我的Java代码中读取int1,int2,int3和int4。我该如何在Java中使用正则表达式匹配。谢谢。 问题答案: 为了避免空值:

  • NowCoder 题目描述 请实现一个函数用来匹配包括 '.' 和 '*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '*' 表示它前面的字符可以出现任意次(包含 0 次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串 "aaa" 与模式 "a.a" 和 "ab*ac*a" 匹配,但是与 "aa.a" 和 "ab*a" 均不匹配。 解题思路 应该注意到,'.' 是