【问题标题】:How do I remove a a list of character sequences from the beginning of a string in Perl?如何从 Perl 中字符串的开头删除字符序列列表?
【发布时间】:2011-07-25 02:29:45
【问题描述】:

我必须从a file 读取行并将它们存储到 Perl 中的哈希中。其中许多行在开头都有特殊的字符序列,我需要在存储之前将其删除。这些字符序列是

| || ### ## @@||

比如如果是||https://ads,我需要得到https://ads;如果###http,我需要得到http

我需要排除这些字符序列。我想通过将所有字符序列排除在一个数组中来做到这一点,然后检查该行是否以这些字符序列开头并删除它们。有什么好的方法可以做到这一点?

我已经做到了:

our $ad_file = "C:/test/list.txt";
our %ads_list_hash = ();

my $lines = 0;

# List of lines to ignore
my @strip_characters = qw /| || ### ## @@||/;

# Create a list of substrings in the easylist.txt file
open my $ADS, '<', $ad_file or die "can't open $ad_file";

while(<$ADS>) {
    chomp;
    $ads_list_hash{$lines} = $_;
    $lines ++;
}

close $ADS;

如果存在任何@strip_characters,我需要添加逻辑以从每行的开头删除它们。

【问题讨论】:

  • 将所有字符放在一个表达式中,然后用它来替换(删除)不需要的字符

标签: perl string substring


【解决方案1】:

对于这项任务来说可能有点过于复杂和笼统,但仍然......

my $strip = join "|", map {quotemeta} @strip_characters;
# avoid bare [] etc. in the RE

# ... later, in the while()
    s/^(?:$strip)+//o; 
    # /o means "compile $strip into the regex once and for all"

【讨论】:

    【解决方案2】:

    为什么不用正则表达式呢?类似的东西

    $line =~ s/^[#@ |]+//;
    

    应该可以。

    【讨论】:

      【解决方案3】:

      如果您想删除 字符 列表(根据您的标题),那么一个非常简单的正则表达式就可以了。
      在循环中,添加以下正则表达式

      while( <$ADS> ) {
          chomp;
          s/^[#@ \|]+//;
          $ads_list_hash{$lines++} = $_;
      }
      

      注意管道字符('|')被转义。 但是,您似乎想删除 表达式 列表。您可以执行以下操作

      while( <$ADS> ) {
          chomp;
          s/^((\|)|(\|\|)|(###)|(##)|(@@\|\|))+//;
         $add_list_hash{$lines++} = $_;
      }
      

      您说表达式列表存储在一个数组或单词中。在您的示例代码中,您使用“qw”创建此数组。如果在编译时不知道表达式列表,您可以在变量中构建正则表达式并使用它。

      my @strip_expression = ... // get an array of strip expressions
      my $re = '^((' . join(')|(',@strip_expression) . '))+';
      

      然后,在循环中使用以下语句: s/$re//;

      最后,关于代码可以说一点与问题无关的事情:使用 Array 而不是 Hash,将整数映射到一组字符串会更合适。除非您有其他要求,否则最好有:

      our @ads_list;    // no need to initialize the array (or the hash) with empty list
      ...
      while( <$ADS> ) {
          chomp;
          s/.../;
          push @ads_list, $_;
      }
      

      【讨论】:

      • 注意管道字符(原文如此)('|')在字符类中不需要转义(原文如此)。
      【解决方案4】:
      $ads_list_hash{$lines} = $_;
      $lines ++;
      

      不要那样做。如果你想要一个数组,使用一个数组:

      push @ads_lines, $_;
      

      Shawn 的编程规则#7:创建数据结构时:如果保持顺序很重要,请使用数组;否则使用哈希。

      【讨论】:

        【解决方案5】:

        因为无论他们是否做了任何事情,替换都会返回,因此您可以使用 替换以搜索字符串以查找您的模式,如果存在则将其删除。

        while( <$ADS> ) {
            next unless s/^\s*(?:[#]{2,3}|(?:@@)?[|]{1,2})\s*//;
            chomp;
            $ads_list_hash{$lines} = $_;
            $lines ++;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-02-12
          • 1970-01-01
          • 2015-10-25
          • 1970-01-01
          • 1970-01-01
          • 2020-12-14
          • 1970-01-01
          相关资源
          最近更新 更多