2014-09-12 31 views
-2

我的目標是要轉換的包含這四種風格條目的約束文件:約束解析用Perl

T10N-Y9C-?: (111.699, 172.003, 26.159) L23CG/L50CG(notL23CG) 
?-?-L147CB: (119.779, 178.656, 42.642) D107C/A77C/D110C 
T89N-V88C-?: (120.308, 175.768, 130.859) orS106C_H41CG/F26CE1 
G149N-G149CA-R109CD: (105.793, 45.249, 43.114) 

隨着輸出,其中每個款式輸出爲:

assign (resid 9 and name C) (resid 23 and name CG or resid 50 and name CG) 3.5 2.5 8.5 ! T10N-Y9C-?: (111.699, 172.003, 26.159) L23CG/L50CG(notL23CG) 
assign (resid 107 and name C or resid 77 and name C or resid 110 and name C) (resid 147 and name CB) 3.5 2.5 8.5 ! ?-?-L147CB: (119.779, 178.656, 42.642) D107C/A77C/D110C 
assign (resid 88 and name C or resid 106 C) (resid 41 and name CG or resid 26 and name CE1) 3.5 2.5 8.5 ! T89N-V88C-?: (120.308, 175.768, 130.859) orS106C_H41CG/F26CE1 
assign (resid 149 and name CA) (resid 109 and name CD) 3.5 2.5 8.5 ! G149N-G149CA-R109CD: (105.793, 45.249, 43.114) 

我有嘗試了很多perl解決方案,但我被卡住了。我能夠與the following perl script第一風格剋制在回答jaypal建議轉換爲my previous question

#!/usr/bin/perl 

use strict; 
use warnings; 
use autodie; 
# 

open my $fh, '<', $ARGV[0]; 

while (<$fh>) { 
    my @values = map { /.(\d+)(\w+)/; $1, $2 } split '/', (split)[-1]; 
    my ($resid, $name) = /^[^-]+-.(\d+)(\w+)-/; 
    print "assign (resid $resid and name $name) ("; 
    print join (" or ", 
     map { "resid $values[$_] and name $values[$_ + 1]" } 
     grep { not $_ % 2 } 0 .. $#values 
    ); 
    print ") 3.5 2.5 8.5 ! $_"; 
} 

Perl是首選,但是Python和awk有其他想法我有這個。請幫忙,我有一個巨大的剋制文件。

+3

你將有很多關於該部分輸入你想翻譯成什麼,而當更具體。看起來你也有一些不平凡的邏輯。 – TLP 2014-09-12 18:47:56

+0

'(not)'語句是實驗預測,但是限制仍然需要在'!'之前打印。這些都是我擁有的4種限制的例子。用我的Perl代碼將第一種樣式限制轉換爲輸出的第一行。但其他三種剋制風格需要轉換爲相應的輸出。 (在這種情況下,與輸出的第2行輸出一樣)。我需要讓腳本確定樣式,然後對它讀取的每一行進行適當的轉換。 – PhysicalChemist 2014-09-12 19:21:03

+2

你需要更徹底地打破你的問題,因爲大多數人閱讀它不會知道區分約束類型的是什麼 - 你已經給出了每種約束和沒有描述的例子。如果你已經設法處理一種剋制,我相信你可以做其他的事情,或者至少做一個有教養的嘗試,你可以請求其他人幫忙完成。 – 2014-09-12 19:51:19

回答

3

你的問題太廣泛了,而且還沒有足夠的信息能夠合理地幫助你。

此外,您所顯示的唯一代碼已在an answer中提供給您以前的問題:Parsing restraints with bash and awk。這並沒有顯示出足夠的努力期望別人提供很多幫助。

但是,從一般意義上說,我會建議你把你的問題分解成你知道如何解析的部分。例如,數據行中有三個明顯的部分。創建一個正則表達式來首先將它們分開。然後,您可以根據您知道的任何格式化規則逐個攻擊這些子問題中的每一個。

以下演示了這種初始解析方法。

use strict; 
use warnings; 
use autodie; 

while (<DATA>) { 
    chomp; 
    # Separate 3 obvious sections of each line 
    my ($name, $numbers, $data) = /^([^:]+): \s* \(([\d\s.,-]+) \) \s* (\S*)/x 
     or die "Unrecognized format at line $.: $_"; 

    # Parse numbers list into an array 
    my @numbers = split /,\s*/, $numbers; 

    # Output current variables - More parsing to come 
    print <<"END_TEXT"; 
Line $. 
    Name = '$name' 
    Numbers = '@numbers' 
    Data = '$data' 
END_TEXT 
} 

__DATA__ 
T10N-Y9C-?: (111.699, 172.003, 26.159) L23CG/L50CG(notL23CG) 
?-?-L147CB: (119.779, 178.656, 42.642) D107C/A77C/D110C 
T89N-V88C-?: (120.308, 175.768, 130.859) orS106C_H41CG/F26CE1 
G149N-G149CA-R109CD: (105.793, 45.249, 43.114) 

輸出:

Line 1 
    Name = 'T10N-Y9C-?' 
    Numbers = '111.699 172.003 26.159' 
    Data = 'L23CG/L50CG(notL23CG)' 
Line 2 
    Name = '?-?-L147CB' 
    Numbers = '119.779 178.656 42.642' 
    Data = 'D107C/A77C/D110C' 
Line 3 
    Name = 'T89N-V88C-?' 
    Numbers = '120.308 175.768 130.859' 
    Data = 'orS106C_H41CG/F26CE1' 
Line 4 
    Name = 'G149N-G149CA-R109CD' 
    Numbers = '105.793 45.249 43.114' 
    Data = '' 
+0

這正是我需要幫助的。非常感謝您的答覆和上面的反饋/編輯。 – PhysicalChemist 2014-09-12 22:28:47