【问题标题】:Parsing a file with D用 D 解析文件
【发布时间】:2012-02-18 01:08:56
【问题描述】:

我是 D 的新手,想解析格式为的生物文件

>name1
acgcgcagagatatagctagatcg
aagctctgctcgcgct
>name2
acgggggcttgctagctcgatagatcga
agctctctttctccttcttcttctagagaga
>name2
gag ggagag

这样我就可以使用相应的“序列”数据捕获“标题”名称 1、名称 2、名称 3,即 ..acgcg... 的东西。

现在我有了这个。但它只会逐行迭代,

import std.stdio;
import std.stream;
import std.regex;


int main(string[] args){
  auto filename = args[1];
  auto entry_name = regex(r"^>(.*)"); //captures header only
  auto fasta_regex = regex(r"(\>.+\n)([^\>]+\n)"); //captures header and correponding sequence

  try {
    Stream file = new BufferedFile(filename);
    foreach(ulong n, char[] line; file) {
      auto name_capture = match(line,entry_name);
      writeln(name_capture.captures[1]);
    }

    file.close();
  }
  catch (FileException xy){
    writefln("Error reading the file: ");
  }

  catch (Exception xx){
    writefln("Exception occured: " ~ xx.toString());
  }
  return 0;
}

我想知道一种提取标题和序列数据的好方法,这样我就可以创建一个关联数组,其中每个项目对应于文件中的一个条目

[name1:acgcgcagagatatagctagatcgaagctctgctcgcgct,name2:acgggggcttgctagctcgatagatcgaagctctctttctccttcttcttctagagaga,.....]

【问题讨论】:

  • D 似乎在生物信息学家中很受欢迎 :)

标签: parsing d dmd


【解决方案1】:

标题在它自己的行上,对吗?那么为什么不检查它并使用附加器来分配值

auto current = std.array.appender!(char[]);
string name;
foreach(ulong n, char[] line; file) {
      auto entry = match(line,entry_name);
      if(entry){//we are in a header line

          if(name){//write what was caught 
              map[name]=current.data.dup;//dup because .current.data is reused
          }
          name = entry.hit.idup;
          current.clear();
      }else{
          current.put(line);
      }
}
map[name]=current.data.dup;//remember last capture

map 是你存储值的地方(string[string] 可以)

【讨论】:

  • 非常感谢!标题在自己的行上。我不明白 c.hit 是从哪里来的 :) 另外我们为什么要分配 entry_name 作为匹配对象?(它应该是一个正则表达式)。最后 map[name] 的类型是什么?抱歉,目前对此我很抱歉。
  • 出现一些编译错误(dmd2):Regex 类型的表达式entry_name!(char)没有布尔值read_file.d(37):错误:未定义的标识符映射,您的意思是函数主吗? read_file.d(39): 错误: 无法将 char[] 类型的表达式 (c.hit()) 隐式转换为字符串 read_file.d(42): 错误: 'Appender!(char[] 类型没有属性'append' )' read_file.d(45): 错误:未定义的标识符映射,你的意思是函数 main 吗? read_file.d(49):错误:未定义的标识符 FileExceptio
  • 非常感谢!已经意识到我需要 cast(string) current.data.dup 将其转换为字符串类型,即在将 map 声明为关联数组之后;字符串[字符串] 映射
  • @eastafri 您不会复制字符串然后将其转换为字符串以获取字符串。你弄错了。 dup 返回调用它的数组的可变副本。 idup 返回调用它的数组的不可变副本。
  • 不错的提示,所以 map[name] = current.data.idup 应该可以解决问题吗?否则编译时 dmd 2.057 会产生此“错误:无法将 char[] 类型的表达式 (_adDupT(& D11TypeInfo_Aa6__initZ,current.data())) 隐式转换为字符串”
【解决方案2】:

这是我没有正则表达式的解决方案(我不相信我们需要正则表达式这样简单的输入):

import std.stdio;
import std.stream;

int main(string[] args) {
  int ret = 0;
  string fileName = args[1];
  string header;
  char[] sequence;
  string[string] content;
  try {  
    auto file = new BufferedFile(fileName);
    foreach(ulong lineNumber, char[] line; file) {
      if (line[0] == '>') {       
        if (header.length > 0) {
          content[header] = sequence.idup;
          sequence.length = 0;
        } // if
        // we have a new header, and new sequence will start after it
        header = line[1..$].idup;
        content[header] = "";
      } else {
          sequence ~= line;
      } // else
    } // foreach
    content[header] = sequence.idup;
    file.close();
  }
  catch (OpenException oe){
    writefln("Error opening file: " ~ oe.toString());
  }
  catch (Exception e){
    writefln("Exception: " ~ e.toString());
  }
  writeln(content);
  return ret;
} // main() function

/+ -------------------------- BEGIN OUTPUT ------------------------------- +
["name3":"gag ggagag", "name1":"acgcgcagagatatagctagatcgaagctctgctcgcgct", "name2":"acgggggcttgctagctcgatagatcgaagctctctttctccttcttcttctagagaga"]
 + -------------------------- END OUTPUT --------------------------------- +/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 2016-09-04
    • 1970-01-01
    • 2020-04-20
    • 2013-12-24
    • 2012-02-25
    • 2023-02-18
    相关资源
    最近更新 更多