使用Ruby和Grep从File中提取名称

时间:2014-04-08 23:52:30

标签: ruby grep

我有一个包含以下数据的文件:

other data
user1=name1
user2=name2
user3=name3
other data

提取我执行以下操作的名称

names = File.open('resource.cfg', 'r') do |f|
  f.grep(/[a-z][a-z][0-9]/)
end

返回以下数组

user1=name1
user2=name2
user3=name3

但我真的只想要名字部分

name1
name2
name3

现在我在文件步骤后执行此操作:

names = names.map do |name|
  name[7..9]
end

有更好的方法吗?使用文件步骤

3 个答案:

答案 0 :(得分:5)

你可以这样做,使用带有正则表达式的String#scan

<强>代码

File.read(FNAME).scan(/(?<==)[A-Za-z]+\d+$/)

<强>解释

让我们从构建文件开始:

FNAME = "my_file"

lines =<<_
other data
user1=name1
user2=name2
user3=name3
other data
_

File.write(FNAME,lines)

我们可以确认文件内容:

puts File.read(FNAME)
other data
user1=name1
user2=name2
user3=name3
other data

现在运行代码::

File.read(FNAME).scan(/(?<==)[A-Za-z]+\d+$/)
  #=> ["name1", "name2", "name3"]

关于我使用的正则表达式的一句话。

(?<=...)

被称为&#34;积极的后视&#34;。无论插入什么代替点都必须紧接在匹配之前,但不是匹配的一部分(因此有时称为&#34;零长度&#34;组)。我们希望比赛遵循等号,所以&#34;正面看后面&#34;如下:

(?<==)

接下来是一个或多个字母,然后是一个或多个数字,然后是行尾,其中包含要匹配的模式。如果您有不同的要求,当然可以更改此设置,例如名称为小写或以大写字母,指定的位数开头等等。

答案 1 :(得分:2)

您的代码是否正常发布?

names = File.open('resource.cfg', 'r') { |f| f.grep(/[a-z][a-z][0-9]/) }
names = names.map { |name| name[7..9] }
=> ["ame", "ame", "ame"]

你可以把它写成一个整洁的小单行内容:

names = File.readlines('resource.cfg').grep(/=(\w*)/) { |x| x.split('=')[1].chomp }

答案 2 :(得分:1)

您只需一步即可完成所有操作:

names = File.open('resource.cfg', 'r') do |f|
    f.grep(/[a-z][a-z][0-9]/).map {|x| x.split('=')[1]}
end