【问题标题】:Restraint Parsing with Perl [closed]使用 Perl 进行约束解析
【发布时间】:2014-09-13 05:04:56
【问题描述】:

我的目标是转换一个包含这四种样式条目的约束文件:

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 解决方案,但我被困住了。我可以使用 jaypal 建议的 the following perl script 来转换第一个样式约束以回答 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 是我对此的其他想法。请帮忙,我有一个巨大的限制文件。

【问题讨论】:

  • 您必须更具体地说明您希望将输入的哪些部分翻译成什么,以及何时翻译。似乎您还涉及一些重要的逻辑。
  • (not ) 语句是实验性的谓词,但约束仍需要在! 之前打印。这些是我拥有的 4 种约束的示例。第一个样式约束使用我拥有的 perl 代码转换为输出的第一行。但是其他三种约束样式需要转换成对应的输出。 (在这种情况下,就像输入的第 2 行到输出的第 2 行一样)。我需要让脚本确定样式,然后对其读取的每一行进行适当的转换。
  • 您需要更彻底地分解您的问题,因为大多数阅读它的人不会知道限制类型的区别——您已经给出了每种限制类型的一个示例,但没有描述。如果你已经设法处理了一种约束,我相信你可以做其他的,或者至少做一个有根据的尝试,你可以向其他人寻求帮助来完成。
  • 如果您要显示在上一个问题的答案中提供的代码,您应该引用该用户。我已经编辑了你的问题。

标签: python bash perl awk


【解决方案1】:

您的问题过于宽泛,几乎没有足够的信息来合理地为您提供帮助。

此外,您显示的唯一代码是在 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    = ''

【讨论】:

  • 这正是我需要帮助的地方。非常感谢您的回答和上面的反馈/编辑。
猜你喜欢
  • 1970-01-01
  • 2014-11-02
  • 2011-11-19
  • 2015-04-12
  • 1970-01-01
  • 2014-10-09
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多