2010-08-23 86 views
1

我有這種如何使用Perl提取數據列?

NAME1    NAME2   DEPTNAME   POSITION 
JONH MILLER  ROBERT JIM  CS     ASST GENERAL MANAGER 

我所要的輸出來名1名2和位置的字符串我怎樣才能使用分流/正則表達式/裝飾/等,並沒有使用CPAN模塊做什麼呢?

+9

你在20天前問你的第一個問題,得到4個答案。在那個時候,你還沒有投票支持任何一個,你沒有接受答案,如果沒有一個答案對你有幫助,你還沒有澄清你的問題來尋求更好的答案。縱觀歷史,有人可能會得出結論:您無意爲本網站貢獻任何東西,而只是採取行動。 – 2010-08-23 17:46:53

+0

對不起,我不知道從現在開始我會對他們投票。謝謝你告訴我。 – Sunny 2010-08-23 18:00:56

+0

@Paul - 仍然是0票:( – DVK 2010-08-24 10:23:06

回答

2

如果輸入數據進來作爲字符串(@strings)的陣列,這

for my $s (@strings) { 
    my $output = join ' ', 
       map /^\s*(.+)\s*$/ ? $1 :(), 
       unpack('A19 A15 x19 A*', $s); 
    print "$output\n" 
} 

將提取並修剪所需的信息。

NAME1 | NAME2 |位置

JONH苗|羅伯特吉姆| ASST GENERAL MANAGER

(在 '|' 被列入由我要的結果更好expalnation)

問候

RBO

+0

解壓縮是一個很好的工具,我們在_Effective Perl Programming_中幾乎覆蓋了這個例子。我希望在下一本書中有一整章包裝:) – 2010-08-23 21:40:46

+0

@brian,「The Book」看起來很有希望,我很想在高級正則表達式(比如現代版的japhys Regex Arcana :http://japhy.perlmonk.org/articles/tpj/2004-summer.html)。此外,在舊版「高級Perl編程」(由Srinivasan撰寫)的第一版中,還有一些非常有趣的高級主題(Perl膽量,嵌入,XS-hand和eval),這些都是從第二版中排除的。 (由Simon Cozens撰寫)。這些(更技術性的)高級主題不屬於任何我知道的實際書籍。 (順便說一句:我昨天訂購了E.P.P的第二版)。 – 2010-08-24 20:11:17

+0

對於Perl的膽量,請_Extending和嵌入Perl_。 _Advanced Perl Programming,1st Edition_的一些有趣部分是_Mastering Perl_的基礎。對於花哨的正則表達式的東西,_Mastering Regular Expressions_。 _Mastering Perl_也有一些奇特的正則表達式,就像_Effective Perl Programming_一樣。也許你只需要閱讀更多書籍。請記住,所有這些東西都在文檔中,所以你不需要購買一本書。 – 2010-08-24 21:09:01

6

這取決於它們是固定長度的字段,還是它們是製表符分隔的。最簡單的(使用分割)是如果它們是製表符分隔的。

my ($name1, $name2, $deptName, $position) = split("\t", $string); 

如果他們固定長度,並假設他們都是,比如說,10個字符長,你可以分析它像

my ($name1, $name2, $deptName, $position) = unpack("A10 A10 A10 A10", $string); 
+0

他們不是固定長度 – Sunny 2010-08-23 17:50:05

+2

@Sunny,那麼你將如何確定哪裏一個字段結束,下一個開始,看看有些字段中有空格嗎?或者你需要用特殊的字符來分隔它們,比如tab,或者你需要把它們放在特定的位置。在第一種情況下,你使用split ,在第二次你使用解包 – 2010-08-23 17:59:18

+0

謝謝保羅 當我想投票它說投票要求15聲望 – Sunny 2010-08-23 18:57:22

0

拆就空白:

@string_parts = split /\s{2,}/, $string; 

這會將$string拆分爲子串列表。分隔符將是正則表達式\s+,這意味着一個或多個空格字符。這包括空格,製表符和(除非我錯了)換行符。

編輯:我看到其中一個要求不是隻在一個空間上拆分,而是在兩個或多個空間上拆分。我相應地修改了正則表達式。

+2

這種解決方案將拆分字符串像「JONH 「,」MILLER「,但它的名字應該是JONH MILLER,這意味着解決方案是不正確的。 – 2010-08-23 18:17:02

+1

@Nikhil:好poi NT。但是你可以像'@string_parts = split/\ s \ s + | \ t \ s * /,$ string'那樣分割多個空格,或者一個標籤和其他可能的空格字符。 – 2010-08-23 18:25:07

+0

@Platinum:那是真的,我正在做我的答案中的同樣的事情。 – 2010-08-23 18:33:35

0

考慮從一個Perl一行程序使用自動分割你的命令行:

$ perl -F/\s{2,}/ -ane 'print qq/@F[0,1,3]\n/' file 

單線程將在兩個或更多個連續空格處分割並打印第一,第二和第四個字段,對應於NAME1,NAME2和POSITION字段。

當然,如果你只有一個空格分隔NAME1和NAME2條目,這將會中斷,但需要更多關於你的文件的信息以確定最佳的行動方案。

+0

downvote的任何理由? – Zaid 2010-08-24 06:27:04

1

假設字段之間的空間不是固定的,所以在兩個或多個空格的基礎上拆分字符串,以便它不會像JONH MILLER那樣將Name拆分爲兩部分

#!/usr/bin/perl 
use strict; 
use warning; 
my $string = "NAME1    NAME2   DEPTNAME   POSITION 
      JONH MILLER  ROBERT JIM  CS     ASST GENERAL MANAGER "; 
my @string_parts = split /\s\s+/, $string; 
foreach my $test (@string_parts){ 
     print"$test\n"; 
} 
1

從樣本中可以看出,單個空間屬於數據,但是2個或更多個連續空間不包含。因此,您可以輕鬆拆分2個或更多空間。我唯一加入的是List::MoreUtils::mesh

use List::MoreUtils qw<mesh>; 
my @names = map { chomp; $_ } split /\s{2,}/, <$file>; 
my @records = map { chomp; { mesh(@names, @{[ split /\s{2,}/ ]}) } } <$file>;