2016-09-28 79 views
2

我有这行代码在一个文本文件分裂空格:分裂空格用perl

my @line_splits = split /\s+/, $ine; 

这是文本文件的一些内容:

1 2016-09-27 14:07:20.084877 
    2 2016-09-27 14:07:20.084998 
    3 2016-09-27 14:07:20.131343 
    4 2016-09-27 14:07:20.131374 
    6 2016-09-27 14:07:20.137359 
    7 2016-09-27 14:07:20.137556 
    8 2016-09-27 14:07:20.137796 
    9 2016-09-27 14:07:20.437769 
10 2016-09-27 14:07:20.437796 
100 2016-09-27 14:07:23.293661 

我目标是获取日期和时间(我知道的是$ line_splits [1]和$ line_splits [2])。

但是,当我跑我的Perl脚本,从1到99的线接错,而在100和起来,我已经得到了我想要的东西。

Time Stamp: 98 2016-09-27    --> line 98 
Time Stamp: 99 2016-09-27    --> line 99 
Time Stamp: 2016-09-27 14:07:23.293661 --> line 100 
Time Stamp: 2016-09-27 14:07:23.299406 --> line 101 
Time Stamp: 2016-09-27 14:07:23.299437 --> line 102 

有人可以告诉我,如果正则表达式有什么问题,或者有另一种方法来做到这一点?

我不知道它是否已经在这里重复,但任何帮助将非常感激。

谢谢:)

+0

跳过前导空格用'/^\ S +(* SKIP)(* F)| \ S + /' –

+0

'$线=〜s/^ \ S + | \ s + $ //'从修剪空白一条线的左侧和右侧。我使用它很多,节省了很多错误。 – yonyon100

+2

你根本不需要跳过前面的空格,因为如果你只是'split'''而不是'split \ \ s + /' – Sobrique

回答

8

哇,很多复杂的答案,但解决方案真的很容易。

只需使用split没有/\s+/正则表达式。

default behaviour - 或者如果您只指定' '进行拆分就会得到的结果是它忽略了前导空格。但与/\s+/它没有。

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Data::Dumper; 

while (<DATA>) { 
    chomp; 
    my @fields = split; 
    print $fields[2],"\n" 
} 

__DATA__ 
    1 2016-09-27 14:07:20.084877 
    2 2016-09-27 14:07:20.084998 
    3 2016-09-27 14:07:20.131343 
    4 2016-09-27 14:07:20.131374 
    6 2016-09-27 14:07:20.137359 
    7 2016-09-27 14:07:20.137556 
    8 2016-09-27 14:07:20.137796 
    9 2016-09-27 14:07:20.437769 
10 2016-09-27 14:07:20.437796 
100 2016-09-27 14:07:23.293661 
+1

Gah。这当然是最好的答案。我知道有一个更好的解决方案,但在我的咖啡因不足的状态下,我无法将它从脑中拉出来。 –

+1

但是如果OP在每个字段之间有多个空格会发生什么?默认分割能够处理这个问题吗? –

+3

是的。默认情况下,split是'任何空白'忽略任何领先。这是因为它与'awk'具有相同的行为。 – Sobrique

1

从各行的左侧修剪空白分裂之前空间:

$line =~ s/^\s+//; 
my @line_splits = split /\s+/, $line; 

像往常一样,@Wiktor遥相呼应用此选项将保留前面的数字少了空白比100:

my @line_splits = split /^\s+(*SKIP)(*F)|\s+/, $line; 

而且在Perl 6将有一个真正的trim功能:

$line .= trim; 
my @line_splits = split /\s+/, $line; 
+0

它是默认的行为!谢谢:) –

+0

可悲的是我在这里没有足够的声望。 –

+0

这种方法实际上删除了主要的空白,而'/^\ s +(* SKIP)(* F)| \ s + /'会保留它们。只需选择你需要的任何一个。 –

1

另一种选择是使用正则表达式来提取您感兴趣的字符串的位(即所有非空白位)。

#!/usr/bin/perl 

use strict; 
use warnings; 
use 5.010; 

while (<DATA>) { 
    my @line_splits = /(\S+)/g; 
    say "Time Stamp: $line_splits[1] $line_splits[2]"; 
} 

__DATA__ 
    1 2016-09-27 14:07:20.084877 
    2 2016-09-27 14:07:20.084998 
    3 2016-09-27 14:07:20.131343 
    4 2016-09-27 14:07:20.131374 
    6 2016-09-27 14:07:20.137359 
    7 2016-09-27 14:07:20.137556 
    8 2016-09-27 14:07:20.137796 
    9 2016-09-27 14:07:20.437769 
10 2016-09-27 14:07:20.437796 
100 2016-09-27 14:07:23.293661