匹配一个单词而不是R中的整行

时间:2015-03-24 16:27:29

标签: regex r

我有一个格式如下的文本文件:

#    title "Secondary Structure"
#    xaxis  label "Time (ns)"
#    yaxis  label "Number of Residues"
#TYPE xy
# subtitle "Structure = A-Helix + B-Sheet + B-Bridge + Turn"
# view 0.15, 0.15, 0.75, 0.85
# legend on
# legend box on
# legend loctype view
# legend 0.78, 0.8
# legend length 2
# s0 legend "Structure"
# s1 legend "Coil"
# s2 legend "B-Sheet"
# s3 legend "B-Bridge"
# s4 legend "Bend"
# s5 legend "Turn"
# s6 legend "A-Helix"
# s7 legend "5-Helix"
# s8 legend "3-Helix"
# s9 legend "Chain_Separator"
   0   637   180   201     7    94   129   300     0    47     1
   1   617   189   191    11    99   121   294     5    48     1
   2   625   183   198     7    97   130   290     0    53     1
   3   625   180   195     5   102   125   300     0    51     1
   4   622   185   196     5    99   117   304     0    52     1
   5   615   192   190     5   106   121   299     0    45     1
   6   629   187   196     7   102   122   304     0    40     1

我试图匹配以" s + number"开头的行。 (s0,s1,s2,... s9)并将值保存在""在列表中,我可以使用此列表命名列。

list <- c("Structure", "Coil","B-Sheet", ..., "Chain_Separato") names(data) <- list

问题在于我无法匹配单个单词,只能匹配整行。

grep('s\\d\\s[a-z]{6}\\s\"([A-z-9]+)\"',readLines("file.xvg"),perl=T,value=T)

[1] "# s0 legend \"Structure\""       "# s1 legend \"Coil\""  
[3] "# s2 legend \"B-Sheet\""         "# s3 legend \"B-Bridge\""
[5] "# s4 legend \"Bend\""            "# s5 legend \"Turn\""
[7] "# s6 legend \"A-Helix\""         "# s9 legend \"Chain_Separator\""

我尝试了几个正则表达式,比如'# s[0-9] [a-z]+ "([A-z-9]+)"',所有正在使用perl,但在R中我总是匹配整行,而不是单词。

用于捕获值的()不是吗?我做错了什么?

3 个答案:

答案 0 :(得分:2)

你可以这样做:

conn = file(fileName,open="r")
lines=readLines(conn)

lst = Filter(function(u) grepl('^# s[0-9]+', u), lines)
result = gsub('.*\"(.*)\".*','\\1',lst)

close(conn)

#> result
#[1] "Structure"       "Coil"            "B-Sheet"         "B-Bridge"        "Bend"            "Turn"            "A-Helix"         "5-Helix"        
#[9] "3-Helix"         "Chain_Separator"

答案 1 :(得分:2)

您可以在fread()中使用系统命令。例如,在名为“file.txt”的文件上,您可以执行

library(data.table)
fread("grep '^# s[0-9]\\+' file.txt", header = FALSE, select = 4)[[1]]
#  [1] "Structure"       "Coil"            "B-Sheet"        
#  [4] "B-Bridge"        "Bend"            "Turn"           
#  [7] "A-Helix"         "5-Helix"         "3-Helix"        
# [10] "Chain_Separator"

注意:这使用data.table dev version 1.9.5

基本上,您在文本中寻找的区域有四列。 ^# s[0-9]\\+会查找以#开头的行,然后是空格,然后是s,然后查找任意数量的数字。 select = 4取最后一列,[[1]]将其从单个列数据表中删除为字符向量。

感谢@BrodieG对正则表达式的帮助。

答案 2 :(得分:1)

如果您使用linuxawk命令可以与read.table <{1}}结合使用pipe

read.table(pipe("awk 'BEGIN {FS=\" \"}/# s[0-9]/  { print$4 }' fra.txt"),
          stringsAsFactors=FALSE)$V1
 # [1] "Structure"       "Coil"            "B-Sheet"         "B-Bridge"  
 # [5] "Bend"            "Turn"            "A-Helix"         "5-Helix"    
 # [9] "3-Helix"         "Chain_Separator"

上述命令也适用于fread

fread("awk 'BEGIN {FS=\" \"}/# s[0-9]/  { print$4 }' fra.txt", 
                 header=FALSE)$V1