2014-04-03 36 views
0

我有一個文本文件,其中包含以適合查看但不適合編程處理的方式打印的數據。這是因爲它使用白色空格作爲分隔符,並且行中有空白條目,但我沒辦法想到區分它們。這就是爲什麼我在這裏提出問題。從Matlab中的文本文件中讀取的數據沒有以一致的方式進行分隔

實施例文件內容:

   Bend Machine Information 
       ======================== 

Bend #  Offset  Twist Angle  Bend Angle Bend Radius 
-------- -------------- -------------- -------------- -------------- 
    1    147.17       13.39   31.75 
    2    116.11   180.00   13.39   31.75 
    3    199.92   305.13   90.00   31.75 
    4    0.10   0.00   90.00   31.75 
    5    68.75            

文件結束。

所以在上面的文字中有扭轉角列第一行的條目,但空格並不表示。

有關如何解析此問題的任何想法? 我想使用Matlab,但也可能使用其他語言(如Perl或Python)。

在此先感謝。

回答

3

在完整的腳本模式,邏輯可以用perl完成如下:

use strict; 
use warnings; 

while (<DATA>) { 
    next if $. < 6; 
    my @vals = $_ =~ /(.{8})(.{15})(.{15})(.{15})(.{15})/; 
    s/\s//g for @vals; 
    print join(',', @vals), "\n"; 
} 

__DATA__ 
       Bend Machine Information 
       ======================== 

Bend #  Offset  Twist Angle  Bend Angle Bend Radius 
-------- -------------- -------------- -------------- -------------- 
    1    147.17       13.39   31.75 
    2    116.11   180.00   13.39   31.75 
    3    199.92   305.13   90.00   31.75 
    4    0.10   0.00   90.00   31.75 
    5    68.75            

或進入一個襯墊轉身:

perl -nle 'next if $.<6; @v=$_=~/(.{8})(.{15})(.{15})(.{15})(.{15})/; s/\s//g for @v; print join(",", @v)' your_file 

輸出:

1,147.17,,13.39,31.75 
2,116.11,180.00,13.39,31.75 
3,199.92,305.13,90.00,31.75 
4,0.10,0.00,90.00,31.75 
5,68.75,,,  

一更好的方法可能是在段之間的空格插入逗號。這樣文件仍然可讀。

perl -pe 'if ($.>5){for $i(8,23,38,53){substr $_,$i,1,","}}' your_file 

輸出:

   Bend Machine Information 
       ======================== 

Bend #  Offset  Twist Angle  Bend Angle Bend Radius 
-------- -------------- -------------- -------------- -------------- 
    1 ,  147.17,    ,   13.39,   31.75 
    2 ,  116.11,  180.00,   13.39,   31.75 
    3 ,  199.92,  305.13,   90.00,   31.75 
    4 ,   0.10,   0.00,   90.00,   31.75 
    5 ,   68.75,    ,    , 
1

這裏有一個Matlab的答案。我認爲@Miller的正則表達式比我的更聰明,並自動識別缺少的字段 - 如果您可以閱讀Perl正則表達式,則可以使用下面的技術在Matlab中實現它。

第一個塊將整個文件讀入單元數組,而不嘗試通過格式字符串讀取。有可能是一個更快的方法來做到這一點。

第二塊跳過的標題行,然後通過行接一行前進到匹配針對行中的正則表達式。請參閱http://www.mathworks.com/help/matlab/matlab_prog/regular-expressions.html

表達式我說要匹配0個或多個空格,1個或多個數字,0或1個,多於0個數字,0個或多個空格。這應該抓住所有的數字,並把它們放在一個單元格陣列中。

如果只有一個數據列丟失,那麼很容易將單元格數組重新排列到所需的數組中。否則,請將regexp()切換爲regexp(file{k}, pattern, 'tokens', 'tokenExtents'),並使用返回的索引來確定抓取的內容(因此缺少的內容)。顯然,我用每一行覆蓋結果,實際上你要麼在循環中處理這個,並保存到結果數組中,要麼保存數組中每個循環迭代的令牌和範圍,以便以後處理。

fid = fopen(<filepath>); 
% The following method is slow but works 
file = []; 
k = 1; 
tline = fgetl(fid); 
while ischar(tline) 
    file{k} = tline; 
    tline = fgetl(fid); 
    k = k+1; 
end 
fclose(fid); 

header_rows = 5; 
pattern = '\s*(\d+\.?\d*)\s*'; 

% Start at the first non-header row and go to the end 
for k = (header_rows+1):length(file) 
    tokens = regexp(file{k}, pattern, 'tokens'); 
    tokens{1,:} 
end 
相關問題