1

这是我正在尝试做的事情:

我想将文本文件读入字符串数组。当文件读取某个字符(主要是;or |)时,我希望字符串终止。

例如下面的文字

你会; 请
递给我| 我的外套?

会像这样被收起来:

$string[0] = 'Would you;';
$string[1] = ' please hand me|';
$string[2] = ' my coat?';

我能在这样的事情上得到一些帮助吗?

4

5 回答 5

6

这会做到的。在保留要拆分的标记的同时使用拆分的技巧是使用零宽度回溯匹配:split(/(?<=[;|])/, ...).

注意:mctylr 的答案(目前评价最高)实际上并不正确——它会在换行符上拆分字段,b/c 它一次只能在文件的一行上工作。

gbacon 使用输入记录分隔符 ( $/) 的答案非常聪明——它既节省空间又节省时间——但我认为我不想在生产代码中看到它。将一个拆分标记放在记录分隔符中,另一个放在拆分中让我觉得有点太不明显了(你必须用 Perl 来解决这个问题......)这将使其难以维护。我也不确定他为什么要删除多个换行符(我认为您没有要求?)以及为什么他只在以“|”结尾的记录结束时才这样做。

# open file for reading, die with error message if it fails
open(my $fh, '<', 'data.txt') || die $!; 

# set file reading to slurp (whole file) mode (note that this affects all 
# file reads in this block)
local $/ = undef; 

my $string = <$fh>; 

# convert all newlines into spaces, not specified but as per example output
$string =~ s/\n/ /g; 

# split string on ; or |, using a zero-width lookback match (?<=) to preserve char
my (@strings) = split(/(?<=[;|])/, $string); 
于 2010-02-12T05:08:40.823 回答
3

一种方法是注入另一个字符,例如\n,每当找到您的特殊字符时,然后在 上拆分\n

use warnings;
use strict;
use Data::Dumper;

while (<DATA>) {
    chomp;
    s/([;|])/$1\n/g;
    my @string = split /\n/;
    print Dumper(\@string);
}

__DATA__
Would you; please hand me| my coat?

打印出来:

$VAR1 = [
          'Would you;',
          ' please hand me|',
          ' my coat?'
        ];

更新:詹姆斯提出的原始问题在一行中显示了输入文本,如上所示__DATA__。由于问题格式不正确,其他人编辑了问题,将 1 行分成 2 行。只有 James 知道是 1 行还是 2 行。

于 2010-02-12T02:17:34.800 回答
1

我更喜欢@toolic 的答案,因为它很容易处理多个分隔符。

但是,如果您想使事情过于复杂,您可以随时尝试:

#!/usr/bin/perl

use strict; use warnings;

my @contents = ('');

while ( my $line = <DATA> ) {
    last unless $line =~ /\S/;
    $line =~ s{$/}{ };
    if ( $line =~ /^([^|;]+[|;])(.+)$/ ) {
        $contents[-1] .= $1;
        push @contents, $2;
    }
    else {
        $contents[-1] .= $1;
    }
}

print "[$_]\n" for @contents;

__DATA__
Would you; please
hand me| my coat?
于 2010-02-12T02:20:51.547 回答
0

类似的东西

$text = <INPUTFILE>;

@string = split(/[;!]/, $text);

应该或多或少地做到这一点。

编辑:我已将“/;!/”更改为“/[;!]/”。

于 2010-02-12T02:14:56.157 回答
0

$/通过将(输入记录分隔符)设置为竖线,让 Perl 为您完成一半的工作,然后提取分号分隔的字段:

#!/usr/bin/perl

use warnings;
use strict;

my @string;

*ARGV = *DATA;

$/ = "|";
while (<>) {
  s/\n+$//;
  s/\n/ /g;
  push @string => $1 while s/^(.*;)//;
  push @string => $_;
}

for (my $i = 0; $i < @string; ++$i) {
  print "\$string[$i] = '$string[$i]';\n";
}

__DATA__
Would you; please
hand me| my coat?

输出:

$string[0] = '你愿意吗;';
$string[1] = '请递给我|';
$string[2] = '我的外套?';
于 2010-02-12T03:51:39.077 回答