用正则表达式查找字符串的一部分

时间:2011-10-31 21:59:37

标签: ruby regex

我有一个像这样的字符串:

"@[30:Larry Middleton]"

我想只返回30.其中30将始终为数字,并且长度可以是1到无穷大。

我试过了:

user_id = result.match(/@\[(\d+):.*]/)

但这会归还一切。我怎么才能回到30岁?

5 个答案:

答案 0 :(得分:5)

如果这真的是你的所有字符串,你不需要匹配模式的其余部分;只匹配连续的整数:

irb(main):001:0> result = "@[30:Larry Middleton]"
#=> "@[30:Larry Middleton]"
irb(main):002:0> result[/\d+/]
#=> "30"

但是,如果您需要将此匹配作为可能在其他位置具有数字的较大字符串的一部分:

irb(main):004:0> result[/@\[(\d+):.*?\]/]
#=> "@[30:Larry Middleton]"
irb(main):005:0> result[/@\[(\d+):.*?\]/,1]
#=> "30"
irb(main):006:0> result[/@\[(\d+):.*?\]/,1].to_i
#=> 30

如果您还需要这个名字:

irb(main):002:0> m = result.match /@\[(\d+):(.*?)\]/
#=> #<MatchData "@[30:Larry Middleton]" 1:"30" 2:"Larry Middleton">
irb(main):003:0> m[1]
#=> "30"
irb(main):004:0> m[2]
#=> "Larry Middleton"

在Ruby 1.9中,您甚至可以命名匹配,而不是使用捕获号:

irb(main):005:0> m = result.match /@\[(?<id>\d+):(?<name>.*?)\]/
#=> #<MatchData "@[30:Larry Middleton]" id:"30" name:"Larry Middleton">
irb(main):006:0> m[:id]
#=> "30"
irb(main):007:0> m[:name]
#=> "Larry Middleton"

如果您需要找到其中许多:

irb(main):008:0> result = "First there was @[30:Larry Middleton], age 17, and then there was @[42:Phrogz], age unknown."
#irb(main):015:0> result.scan /@\[(\d+):.*?\]/
#=> [["30"], ["42"]]
irb(main):016:0> result.scan(/@\[(\d+):.*?\]/).flatten.map(&:to_i)
#=> [30, 42]
irb(main):017:0> result.scan(/@\[(\d+):(.*?)\]/).each{ |id,name| puts "#{name} is #{id}" }
Larry is 30
Phrogz is 42

答案 1 :(得分:2)

试试这个:

user_id = result.match(/@\[(\d+):.*]/)[1]

答案 2 :(得分:1)

你忘了逃避']':

user_id = result.match(/@\[(\d+):.*\]/)[1]

答案 3 :(得分:1)

我不知道红宝石,但如果它支持lookbehinds和lookaheads:

user_id = result.match(/(?<@\[)\d+(?=:)/)

如果没有,你应该有一些方法从比赛中检索子模式 - 再次,我不知道如何。

答案 4 :(得分:1)

我更喜欢String#scan来满足我的大部分正则表达式需求,这就是我要做的事情:

results.scan(/@\[(\d+):/).flatten.map(&:to_i).first

关于获取名称的第二个问题:

results.scan(/(\d+):([A-Za-z ]+)\]$/).flatten[1]

扫描将始终返回子字符串匹配数组:

"@[123:foo bars]".scan(/\d+/) #=> ['123']

如果在parens中包含模式,那么这些“子模式”的每个匹配都将包含在子数组中:

"@[123:foo bars]".scan(/(\d+):(\w+)/) #=> [['123'], ['foo']]

这就是为什么我们必须对涉及子模式的结果做平:

[['123'], ['foo']].flatten = ['123', 'foo']

它总是返回字符串,这就是为什么在第一个例子中需要转换为整数的原因:

['123'].to_i = 123

希望这有用。