2016-09-28 68 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