English 中文(简体)
如何在Ruby字符串中解析最后一组括号内的子字符串?
原标题:
  • 时间:2009-03-28 06:52:38
  •  标签:

In my ruby on rails app, I am trying to build a parser to extract some metadata out of a string.

Let s say the sample string is:

The quick red fox (frank,10) jumped over the lazy brown dog (ralph, 20).

我想从最后一个 ( ) 出现的子字符串中提取出子字符串。

因此,无论字符串中有多少个( ),我都想要得到“ralph, 20”。

Is there a best way to create this ruby string extraction ... regexp?

谢谢 (xiè xiè)

约翰

最佳回答

我会尝试这个(这里我的正则表达式假设第一个值是字母数字,第二个值是数字,可以根据需要进行调整)。这里扫描所有出现的结果作为一个数组,并且-1告诉我们只获取最后一个,这似乎正是您所要求的:

>> foo = "The quick red fox (frank,10) jumped over the lazy brown dog (ralph, 20)."
=> "The quick red fox (frank,10) jumped over the lazy brown dog (ralph, 20)."
>> foo.scan(/(w+, ?d+)/)[-1]
=> "(ralph, 20)"
问题回答

看起来你想要一个 sexeger。它们通过反转字符串,在字符串上运行反向正则表达式,然后将结果反转来工作。这里有一个例子(请原谅我的代码,我不真的知道 Ruby):

#!/usr/bin/ruby

s = "The quick red fox (frank,10) jumped over the lazy brown dog (ralph, 20).";

reversed_s = s.reverse;
reversed_s =~ /^.*?)(.*?)(/;
result = $1.reverse;
puts result;

The fact that this is getting no up votes tells me nobody clicked through to read why you want to use a sexeger, so here is are the results of a benchmark:

do they all return the same thing?
ralph, 20
ralph, 20
ralph, 20
ralph, 20
                        user     system      total        real
scan greedy         0.760000   0.000000   0.760000 (  0.772793)
scan non greedy     0.750000   0.010000   0.760000 (  0.760855)
right index         0.760000   0.000000   0.760000 (  0.770573)
sexeger non greedy  0.400000   0.000000   0.400000 (  0.408110)

这里是基准:

#!/usr/bin/ruby

require  benchmark 

def scan_greedy(s)
    result = s.scan(/([^)]*)/x)[-1]
    result[1 .. result.length - 2]
end

def scan_non_greedy(s)
    result = s.scan(/(.*?)/)[-1]
    result[1 .. result.length - 2]
end

def right_index(s)
    s[s.rindex( ( ) + 1 .. s.rindex( ) ) -1]
end

def sexeger_non_greedy(s)
    s.reverse =~ /^.*?)(.*?)(/
    $1.reverse
end

s = "The quick red fox (frank,10) jumped over the lazy brown dog (ralph, 20).";

puts "do they all return the same thing?", 
    scan_greedy(s), scan_non_greedy(s), right_index(s), sexeger_non_greedy(s)

n = 100_000
Benchmark.bm(18) do |x|
    x.report("scan greedy")        { n.times do; scan_greedy(s); end }
    x.report("scan non greedy")    { n.times do; scan_non_greedy(s); end }
    x.report("right index")        { n.times do; scan_greedy(s); end }
    x.report("sexeger non greedy") { n.times do; sexeger_non_greedy(s); end }
end

一种简单的非正则表达式解决方案:

string = "The quick red fox (frank,10) jumped over the lazy brown dog (ralph, 20)."
string[string.rindex( ( )..string.rindex( ) )]

Example:

irb(main):001:0> string =  "The quick red fox (frank,10) jumped over the lazy brown dog (ralph, 20)."
=> "The quick red fox (frank,10) jumped over the lazy brown dog (ralph, 20)."
irb(main):002:0> string[string.rindex( ( )..string.rindex( ) )]
=> "(ralph, 20)"

没有括号:

irb(main):007:0> string[string.rindex( ( )+1..string.rindex( ) )-1]
=> "ralph, 20"




相关问题
热门标签