1

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

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

文件内容是这样的:

101|~约翰|~这条线是
破碎和显示
打印空间|~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 之前 = 拆分 (/\|\~/); 它根据我的要求打印了详细信息,但没有在我的数据库表中正确插入数据。请建议我该怎么做?提前致谢。

4

4 回答 4

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";

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

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

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

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

  3. 当某些东西没有改变时,你应该让它成为一个常量。这会将您所有不变的数据放在一个地方,并允许您定义神秘数字,例如PI = 3.1416. 不幸的是,除非您知道Perl deep dark secret,否则无法轻松地将常量插入到输出中。

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

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

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

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

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

于 2013-04-09T15:31:34.410 回答
0

您需要在拆分之前将“it”变量切碎。

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

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

while ( my $line= <FH> )
{
   chomp ($line);
   ...
于 2013-04-08T01:56:43.407 回答
0
open FH, 'D:\Learning\Test.txt' or die $!;
my @data_line;
while (<FH>)
{
chomp;
@data_line = split (/\|\~/);
print @data_line;
}

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

于 2013-04-08T02:01:29.253 回答
0

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

perl -pi -e 's/\|\~//g;s/\n/ /g' test.txt
于 2013-04-08T05:41:15.840 回答