Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby中的正则表达式跳过了双正斜杠_Ruby_Regex - Fatal编程技术网

Ruby中的正则表达式跳过了双正斜杠

Ruby中的正则表达式跳过了双正斜杠,ruby,regex,Ruby,Regex,我需要帮助在Ruby中使用一个失败的正则表达式,我不知道为什么。 我使用Ruby从一个大型生物数据库中获取部分文本,该数据库具有以下功能 结构(为了简单起见,我将只显示两项): i、 e.数据库条目以包含IPI代码的行开始,以双正斜杠结束。我想检索与特定IPI代码相关的信息。 假设我只想获取从IPI代码到以下/的IPI00303292.1的文本行 /(IPI00303292\.1)。*\///mregex的红球测试将捕获整个显示文本(即两个条目),识别最后一个//,同时跳过两个文本之间的第二个

我需要帮助在Ruby中使用一个失败的正则表达式,我不知道为什么。 我使用Ruby从一个大型生物数据库中获取部分文本,该数据库具有以下功能 结构(为了简单起见,我将只显示两项):

i、 e.数据库条目以包含IPI代码的行开始,以双正斜杠结束。我想检索与特定IPI代码相关的信息。 假设我只想获取从IPI代码到以下
/
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 end
code
现在的问题是,我在输出文件中获得了两个正命中的副本。请帮助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