Ruby中的正则表达式跳过了双正斜杠
我需要帮助在Ruby中使用一个失败的正则表达式,我不知道为什么。 我使用Ruby从一个大型生物数据库中获取部分文本,该数据库具有以下功能 结构(为了简单起见,我将只显示两项): i、 e.数据库条目以包含IPI代码的行开始,以双正斜杠结束。我想检索与特定IPI代码相关的信息。 假设我只想获取从IPI代码到以下Ruby中的正则表达式跳过了双正斜杠,ruby,regex,Ruby,Regex,我需要帮助在Ruby中使用一个失败的正则表达式,我不知道为什么。 我使用Ruby从一个大型生物数据库中获取部分文本,该数据库具有以下功能 结构(为了简单起见,我将只显示两项): i、 e.数据库条目以包含IPI代码的行开始,以双正斜杠结束。我想检索与特定IPI代码相关的信息。 假设我只想获取从IPI代码到以下/的IPI00303292.1的文本行 /(IPI00303292\.1)。*\///mregex的红球测试将捕获整个显示文本(即两个条目),识别最后一个//,同时跳过两个文本之间的第二个
/
的IPI00303292.1
的文本行
/(IPI00303292\.1)。*\///m
regex的红球测试将捕获整个显示文本(即两个条目),识别最后一个//
,同时跳过两个文本之间的第二个
更新:
嗨,基于你的宝贵建议,我想我很快就能得到一个适合我的目的的可用程序了。代码是:
matches = []
no_matches = []
ipi = File.open('mini_alphaIPI.txt').collect do | var | # read the file containing IPI search codes
var = var.chomp
db = File.open('mini_human.dat') # read the file containing IPI data
db.readlines.map(&:chomp).slice_before(%r(\A//)).each do |db_record|
db_record.shift
next if db_record.empty?
matches.push(db_record) if db_record.first.include?(var)
if db_record.first.include?(var) then
matches.push(db_record)
else
no_matches.push(var)
end
end
end
File.open('out_raw.txt', "wb") do |file|
matches.each do |z|
file.puts z
end
end
现在要解决的最后一个问题是,我在输出文件中得到了两份正确选择的正点击。我无法摆脱这样的错误。请帮助。这是使用贪婪量词
*
造成的典型问题。请使用非贪婪量词*?
。Ruby附带了一个很好的工具,可以解决此类问题:
require 'pp'
DATA.readlines.slice_before(%r(\A//)).each do |db_record|
pp db_record
end
__END__
//
ID IPI00303292.1 IPI; PRT; 538 AA.
AC IPI00303292;
DR Superfamily; SSF48371; ARM; 1.
DR UniProt/Swiss-Prot; P52294; IMA1_HUMAN; M.
DR CleanEx; HS_KPNA1; -; -.
//
ID IPI00301082.1 IPI; PRT; 309 AA.
AC IPI00301082;
DT 06-JUN-2003 (IPI Human rel. 2.20, Created)
//
运行代码输出:
["//\n",
"ID IPI00303292.1 IPI; PRT; 538 AA.\n",
"AC IPI00303292;\n",
"DR Superfamily; SSF48371; ARM; 1.\n",
"DR UniProt/Swiss-Prot; P52294; IMA1_HUMAN; M.\n",
"DR CleanEx; HS_KPNA1; -; -.\n"]
["//\n",
"ID IPI00301082.1 IPI; PRT; 309 AA.\n",
"AC IPI00301082;\n",
"DT 06-JUN-2003 (IPI Human rel. 2.20, Created)\n"]
["//\n"]
如果要跳过第一个子数组/
条目,请使用:
pp db_record[1..-1]
或:
清理后,代码如下所示:
require 'pp'
DATA.readlines.map(&:chomp).slice_before(%r(\A//)).each do |db_record|
db_record.shift
pp db_record
end
["ID IPI00303292.1 IPI; PRT; 538 AA.",
"AC IPI00303292;",
"DR Superfamily; SSF48371; ARM; 1.",
"DR UniProt/Swiss-Prot; P52294; IMA1_HUMAN; M.",
"DR CleanEx; HS_KPNA1; -; -."]
["ID IPI00301082.1 IPI; PRT; 309 AA.",
"AC IPI00301082;",
"DT 06-JUN-2003 (IPI Human rel. 2.20, Created)"]
[]
运行它看起来像:
require 'pp'
DATA.readlines.map(&:chomp).slice_before(%r(\A//)).each do |db_record|
db_record.shift
pp db_record
end
["ID IPI00303292.1 IPI; PRT; 538 AA.",
"AC IPI00303292;",
"DR Superfamily; SSF48371; ARM; 1.",
"DR UniProt/Swiss-Prot; P52294; IMA1_HUMAN; M.",
"DR CleanEx; HS_KPNA1; -; -."]
["ID IPI00301082.1 IPI; PRT; 309 AA.",
"AC IPI00301082;",
"DT 06-JUN-2003 (IPI Human rel. 2.20, Created)"]
[]
哪些产出:
["ID IPI00303292.1 IPI; PRT; 538 AA.",
"AC IPI00303292;",
"DR Superfamily; SSF48371; ARM; 1.",
"DR UniProt/Swiss-Prot; P52294; IMA1_HUMAN; M.",
"DR CleanEx; HS_KPNA1; -; -."]
[“ID IPI00303292.1 IPI;PRT;538 AA。”,
“AC IPI00303292;”,
“DR Superfamily;SSF48371;ARM;1。”,
“UniProt博士/瑞士Prot;P52294;IMA1_HUMAN;M.”,
“CleanEx博士;HS_KPNA1;-;-。”]
- 列表项
也匹配/
几乎用这个正则表达式实现了:
%r{
//\n # Match '//' and new line
(?<item> # Capture the item...
[\n\w\s.,;\-\(\)]+ # And here comes the !"#%&@ł
) # You need this to match a single appearance of '/'
}x # e.g., not '//', and partial regex negation is a bit tricky...
你好:这个管用
%r{
(//)?\n
(?.+?)
\n//
}xm
但是这只是出于好奇,说真的,只需使用
split('/')
你能粘贴到该rubular测试的链接吗?首先按“/”分割,然后按结果数组中每个项目的第一个字符进行选择不是更容易吗?e、 g.db|u entries.split(“/”)。选择{item | item.start|u with?“ID IPI00303292.1”}
使其成为db|u entries.split(“/”)。选择{item | item.start|u with?“ID IPI00303292.1”}
感谢您有用的回复。由于IPI代码将是多个(从一个文件中读取,每一个都放在一行上,并放入一个变量),因此使用您的方法,我将最终得到一个数组数组,我不知道如何管理或将其作为文本文件转储。这就是为什么我试图一次把整个文本块都弄脏的原因。我将尝试找出如何处理表,但同时,如果您能建议如何将表转储到一个文本文件中(格式为输入),我将不胜感激。处理数组数组是所有编程语言中的一项基本知识,因为它们是一种中间数据结构。你每天会多次遇到它们。对于程序员来说,深入研究并发现如何做一些事情也是一种基本特征,因此,搜索和阅读,如果一周后你还没有弄明白,请给我一个评论,我会扩展答案。嗨,我想我差不多能得到一个可用的程序了。这里是:Hi,code
ipi=File.open('mini_alphaIPI.txt')。collect do | var | |#IPIs var=var.chomp db=File.open('mini_human.dat')#data db.readlines.map(&:chomp)。在(%r(\A/))之前切片。如果db | record.empty.empty,每个都做| db | record | db | record.shift下一步?匹配.push(db_记录)if db_record.first.include?(var)if db_record.first.include?(var)然后匹配.push(db_记录)否则不匹配.push(var)结束文件.open('out_raw.txt',“wb”)do | file | matches.each do | z | file.puts z end endcode
现在的问题是,我在输出文件中获得了两个正命中的副本。请帮助HI,printf(“%d\n”,42)/*ipi=File.open('mini_alphaIPI.txt')。collect do | var |#IPIs var=var.chomp db=File.open('mini_human.dat'))#data db.readlines.map(&:chomp)。在(%r(\A/)之前切片。如果db_record.empty,每个do | db| u record | db | record.shift?matches.push(db_record)if db_record.first.include?(var)if db_record.first.include?(var)然后matches.push(db_record)否则不匹配。push(var)end File.open('out_raw.txt',“wb”)do | File | matches.each do | z | File.puts z end*/问题是我在输出文件中得到了两个正命中的副本。请帮忙
["ID IPI00303292.1 IPI; PRT; 538 AA.",
"AC IPI00303292;",
"DR Superfamily; SSF48371; ARM; 1.",
"DR UniProt/Swiss-Prot; P52294; IMA1_HUMAN; M.",
"DR CleanEx; HS_KPNA1; -; -."]
%r{
//\n # Match '//' and new line
(?<item> # Capture the item...
[\n\w\s.,;\-\(\)]+ # And here comes the !"#%&@ł
) # You need this to match a single appearance of '/'
}x # e.g., not '//', and partial regex negation is a bit tricky...
DATA.split('//').each do |item|
item.each_line do |line|
# etc
end
end
%r{
(//)?\n
(?<item>.+?)
\n//
}xm