我有一个包含以下数据的文件:
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
有更好的方法吗?使用文件步骤
答案 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