通过与数组进行比较,用正则表达式简化长if-else链

问题描述 投票:0回答:3
for (my $j = 0; $j <100000; $j++){
    my $outcome = rand();
    for (my $k = 0; $k < @cum_sum; $k++){
        if ($cum_sum[$k] >= $outcome){
            if ($keys[$k] =~ m/\"|\/|\<|\>|\\|\`|\~|\@|\#|\$|\%|\^|\*|[0-9]/) {
                print $out "";
            }
            if ($keys[$k] =~ m/\s/){
                print $out " ";
            }
            elsif ($keys[$k] =~ m/\&/){
                print $out " and ";
            }
            elsif ($keys[$k] =~ m/\!/){
                print $out "! ";
            }
            elsif ($keys[$k] =~ m/\:/){
                print $out ": ";
            }
            elsif ($keys[$k] =~ m/\'/){
                print $out "' ";
            }
            elsif ($keys[$k] =~ m/\./){
                print $out ". ";
            }
            elsif ($keys[$k] =~ m/\;/){
                print $out "; ";
            }
            elsif ($keys[$k] =~ m/\?/){
                print $out "? ";
            }
            elsif ($keys[$k] =~ m/\,/){
                print $out ", ";
            }
            else {
                print $out "$keys[$k]";
            }
            last;
        }
    }
#   print "$outcome\n";
}

我通常需要帮助来简化我拥有的elsif语句的长链。外部for循环中的逻辑起作用。@keys是两个字符(字母)字符串的数组。

[我正在尝试通过比较elsif的二元图和标点符号@key的数组来使@punctuation = qw(! : " ' ; ? , .)语句更高效

然后,如果Digram确实在标点符号数组中包含标点符号之一,则Digram会更改为“ punctuation_mark”,例如“一个!” ->“!”

最终结果是,我不对@punctuation中的任何一个使用正则表达式。

但是,我不确定如何实施此更改。

谢谢!

arrays regex perl if-statement
3个回答
1
投票

[和第一个正则表达式一样使用替代,但是要捕获匹配项,并用use $1替换单词

$1

评论

  • [my $re_punct = join '|', map { quotemeta } qw(& ! : ' . ; ? ,); #' for my $j (0..100_000) { my $outcome = rand(); for my $k (0..$#cum_sum) { ... if ($keys[$k] =~ /($re_punct)/) { $keys[$k] = "$1 " } ... } } 由所有[ASCII非“单词”字符

  • 转义为quotemeta
  • 语法:\$#ary中最后一个元素的索引,正好适合循环遍历数组索引

  • @ary比等效的C样式for my $i ($beg .. $end)循环

    ] >>
  • 提出的逻辑提出了一个问题:如果两个字符都是标点符号怎么办?


请注意您要执行的操作“

通过与数组比较

例如,您可以使用for。它会像

List::MoreUtils::first_value

use List::MoreUtils qw(first_value);

my @punc = map { quotemeta }  qw(& ! : ' . ; ? ,);  #'

foreach my $word (@words) {
    if (my $match = first_value { $word =~ /$_/ } @punct) {
        $word = $match;
    }
}
(或first_value)返回该块返回true的firstval的第一个元素,如果没有,则返回@punctundef别名为$word的当前处理元素,对其进行更改将更改数组元素。这样您就可以更换了。

但是,您仍然必须处理正则表达式并避免使用标点符号(至少其中的一部分)。因此,我认为解决这个麻烦没有任何好处。在这种情况下,“直接”正则表达式更加清晰。


甚至编译语言都以这种方式发展。 @words引入了C++11range-based for loop
和链接(不是标准,而是标准参考)说

与传统的for (auto var: container) ... // (really, const auto&), or auto&, or auto&& 循环相比,更具可读性[...

在Perl中,

事情如何完成;只需使用它。

2
投票
为了简化代码,使用for CPAN模块可能很有意义。主要思想是使用regexpr作为键构建哈希,因此您可以通过匹配轻松找到相关值:

0
投票
所以,看它有两种情况:
© www.soinside.com 2019 - 2024. All rights reserved.