2

我正在编写一个 Ruby 脚本来遍历一个文本文件并在每行中提取第二次出现的正则表达式模式。以下是一行文本的示例:

gi|324021737|ref|NM_001204301.1|    gi|324021738|ref|NP_001191230.1|    100.00  459 0   0   1080    2456    294 752 0.0  905

我要获取的数字是gi|324021738上面示例中的数字,但不是gi|324021737行首的数字。这些值始终以 开头gi|,但其后的位数会有所不同。

仅将 Regex 的第二个匹配项附加到字符串数组的最有效方法是什么?

4

3 回答 3

2

你可以使用这个正则表达式: -

"^gi.*?(gi\|\d+).*?$"

并让第 1 组脱离它。

于 2012-12-25T21:33:55.917 回答
2

这将比使用split('|')正则表达式更好地处理:

array = []

text = 'gi|324021737|ref|NM_001204301.1|    gi|324021738|ref|NP_001191230.1|    100.00  459 0   0   1080    2456    294 752 0.0  905'
array << text.split('|')[4, 2].map(&:lstrip)
=> [["gi", "324021738"]]

管道(“|”)通常用于分隔数据库输出中的字段,类似于逗号分隔值文件 (CSV)。

Ruby 的CSV甚至是更好的选择:

require 'csv'

text = 'gi|324021737|ref|NM_001204301.1|    gi|324021738|ref|NP_001191230.1|    100.00  459 0   0   1080    2456    294 752 0.0  905'

array = []
CSV.parse(text, :col_sep => '|') do |row|
  array << row[4, 2].map(&:lstrip)
end

array
=> [["gi", "324021738"]]

使用 CSV 可能比拆分更好,尤其是比简单的正则表达式更好的原因是,当分隔文件嵌入另一个字段时,它通常会转义分隔字符。捕获该条件的正则表达式很难编写和维护。split也可能做错事,这就是为什么最好依赖预先构建/预先测试的“轮子”,如 CSV。

于 2012-12-25T23:32:34.737 回答
0

我花了几秒钟来理解@Rohit 发布的正则表达式。

这是使用拆分的替代答案。使用“”字符(空格)将字符串分成组。然后使用“|”分割索引 1 处的元素。获取索引 1 处的元素。这就是您要查找的数字。

s = "gi|324021737|ref|NM_001204301.1|    gi|324021738|ref|NP_001191230.1|    100.00  459 0   0   1080    2456    294 752 0.0  905"
s.split(" ")[1].split("|")[1]

=> "324021738"
于 2012-12-25T23:40:00.250 回答