【问题标题】:Removing whitespace and line breaks between delimiters in Perl在 Perl 中删除分隔符之间的空格和换行符
【发布时间】:2013-04-10 03:09:00
【问题描述】:

我是 Perl 新手,想解决一个问题,但没有成功。我正在尝试从文本文件中读取数据。代码是:

open FH, 'D:\Learning\Test.txt' or die $!;
my @data_line;
while (<FH>)
{
@data_line = split (/\|\~/);
print @data_line;
}

文件内容是这样的:

101|~John|~这一行是
破碎和显示
打印空间|~version123|~data|~|~|~
102|~Abrahim|~这是要打印的行|~version1.3|~|~|~|~

输出是:

101John 这行是
破碎和显示
printversion123data 中的空间
102AbrahimThis is a line to be printversion1.3

我只想在分隔符之间的一行中显示数据,例如:

101John 此行已损坏并在 printversion123data 中显示空格
102AbrahimThis is a line to be printversion1.3

请建议我该怎么做。我也试过chomp(@data_line),但没用。 我使用的是 Windows 操作系统。

我想在表格的不同字段中插入这些“|~”分隔值。我补充说: $_ =~ s/\n//g; @data_line 之前 = 拆分 (/\|\~/); 它根据我的要求打印了详细信息,但没有在我的数据库表中正确插入数据。 请建议我该怎么做?提前致谢。

【问题讨论】:

    标签: perl


    【解决方案1】:

    稍微改写:

    use strict;
    use warnings;
    use feature qw(say);               #See note #1
    
    use autodie;                       #See note #2
    
    use constant FILE => 'D:/Learning/Test.txt';  #See note #3
    
    open my $fh, "<", FILE;            #See note #4
    my $desired_output;
    while ( my $line = <DATA> ) {      #See note #5
        chomp $line;                   #See note #6
        $line =~ s/\|~//g;
        if ( $desired_output ) {
           if ( $line =~ /^\d+/ ) {
               $desired_output .= "\n$line";
           }
           else {
               $desired_output .= " $line";
           }
        }
        else {                         #See note #7
           $desired_output = $line;
        }
    }
    close $fh;                         #See note #8
    say "$desired_output";
    

    为什么不直接使用 substitute 命令完全删除 字段分隔符,而不是使用拆分?另请注意,我将输出保存为一条连续的线。内部if 结构比我喜欢的要复杂一些,但很容易理解。如果$desired_output 中没有数据,我只需将$desired_output 设置为等于我的行。否则,我会检查$line 是否以数字开头。如果是这样,我会将\n 附加到$desired_output,然后附加$line。否则,我会附加一个空格,然后是$line

    现在是我的笔记。这或多或少是用现在所谓的标准 Perl 风格编写的。这包括一些好的建议(使用strictwarnings 等)以及现代程序的布局方式。例如,使用下划线分隔变量名中的单词,而不是使用驼峰式大小写($desired_output$desiredOutput)。 Damian Conway 的Perl Best Practices 涵盖了很多内容。这些可能不是我想做的事情,但我这样做是因为其他人都在这样做。而且,遵循标准通常比抱怨更重要。这是关于维护和可读性。你随波逐流。

    1. 始终将这三行放在所有程序中。前两个将捕获 90% 的编程错误,use features qw(say); 允许您使用 say 而不是 print。它使您不必在最后添加\n,这可能比现在听起来更重要。相信我,如果可能,您宁愿使用say 而不是print

    2. use autodie 在 Perl 中处理程序不应继续运行的许多情况。例如,如果您无法读取文件,则最好不要继续您的程序。 autodie 的好处在于,当您忘记测试命令的返回值时,它会停止您的程序。

    3. 当某些内容没有改变时,您应该将其设为constant。这会将您的所有不变数据放在一个位置,并允许您定义像PI = 3.1416 这样的神秘数字。不幸的是,除非您知道Perl deep dark secret,否则无法轻松地将常量插入到输出中。

    4. 打开文件时,使用打开命令的three parameter form,并使用标量文件句柄。与使用旧的全局句柄相比,您可以更轻松地将标量文件句柄传递给子例程。

    5. 不要使用$_,除非你必须使用自动变量(如grepmap)。它不会提高可读性或加快执行速度。而且,它有让你陷入困境的倾向。它是所有包中的全局变量,可能会在您不知情的情况下受到影响。

    6. 我总是chomp 每次我读入可能在末尾有新行的数据,即使以后可能会很方便。行尾的新行可能会导致正则表达式的各种惊愕。这可以在 while 本身内部完成:while ( chomp ( my $line = &lt;$fh&gt; ) ),但这不会增加可读性或速度。

    7. 注意我的缩进和我使用括号的方式。这是现在的首选标准。我花了几年时间才忘记了在 Pascal 和 K&R 风格 C 中的做法。不妨尽早以正确的方式学习它。

    8. 完成后始终关闭文件句柄。这只是很好的形式。

    【讨论】:

      【解决方案2】:

      您需要在拆分前切掉“it”变量。

      while (<FH>)
      {
      chomp ($_);
      @data_line = split (/\|\~/);
      print @data_line;
      }
      

      我通常使用显式变量来使其更具可读性。

      while ( my $line= <FH> )
      {
         chomp ($line);
         ...
      

      【讨论】:

        【解决方案3】:
        open FH, 'D:\Learning\Test.txt' or die $!;
        my @data_line;
        while (<FH>)
        {
        chomp;
        @data_line = split (/\|\~/);
        print @data_line;
        }
        

        您可以使用 chomp 删除文件中的“/n”。

        【讨论】:

          【解决方案4】:

          这一个班轮会帮助你。但它会改变你的输入文件

          perl -pi -e 's/\|\~//g;s/\n/ /g' test.txt
          

          【讨论】:

          • 嗨,我添加了这样的内容:$_ =~ s/\n//g; @arr = 拆分 (/\|\~/);它在屏幕上打印了正确的输出,但是如果我想在数据库表中插入这些值,则它不能正确插入数据。
          猜你喜欢
          • 1970-01-01
          • 2023-03-15
          • 2013-12-08
          • 1970-01-01
          • 1970-01-01
          • 2021-02-23
          • 1970-01-01
          • 2014-02-27
          • 1970-01-01
          相关资源
          最近更新 更多