2014-09-12 202 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