从包含“[”的Ruby中的字符串中提取子字符串

时间:2013-10-21 09:09:03

标签: ruby regex

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

[date,ip]:string{[0.892838,1.28820,8.828823]}

我想将数据0.892838,1.28820,8.828823提取到一个字符串中以供以后处理。

我使用模式line = String ~= /\\[/来获取"["出现的位置 但对于上面的输入,我收到此错误消息:

premature end of char-class /\\[/

3 个答案:

答案 0 :(得分:2)

这是怎么回事?

str = 'date,ip]:string{[0.892838,1.28820,8.828823]}'
str.scan(/\d+.\d+/)
# => ["0.892838", "1.28820", "8.828823"]

答案 1 :(得分:1)

使用捕获组:

'[date,ip]:string{[0.892838,1.28820,8.828823]}' =~ /{\[(.*?)\]}/
# => 16
$1            # => "0.892838,1.28820,8.828823"
$1.split(',') # => ["0.892838", "1.28820", "8.828823"]

答案 2 :(得分:0)

我很容易做到:

require 'fruity'

str = '[date,ip]:' + ('string' * 1) + '{[0.892838,1.28820,8.828823]}'
compare do
  arup { str.scan(/\d+.\d+/) }
  falsetrue { str =~ /{\[(.*?)\]}/; $1.split(',') }
  ttm { str[/\[([^\]]+)\]}$/, 1].split(',') }
end

# >> Running each test 2048 times. Test will take about 1 second.
# >> falsetrue is similar to ttm
# >> ttm is faster than arup by 2x ± 0.1

string部分越长,各种尝试的运行时间就越多:

require 'fruity'

str = '[date,ip]:' + ('string' * 1000) + '{[0.892838,1.28820,8.828823]}'
compare do
  arup { str.scan(/\d+.\d+/) }
  falsetrue { str =~ /{\[(.*?)\]}/; $1.split(',') }
  ttm { str[/\[([^\]]+)\]}$/, 1].split(',') }
end

# >> Running each test 512 times. Test will take about 2 seconds.
# >> ttm is faster than falsetrue by 60.00000000000001% ± 10.0%
# >> falsetrue is faster than arup by 13x ± 1.0

“ttm”结果提高速度的原因是'$'。该锚为正则表达式引擎提供了解立即搜索位置所需的信息。如果没有它,它将从字符串的开头开始向前搜索,因此'string'组件越长,找到所需模式所需的时间就越长。

使用基准测试表达式,您可以找到特定任务的最佳平均速度和表达式。

如果“string”部分总是很短,那么单次传递的差异是如此之小以至于无关紧要,然后使用最容易读取(并且易于维护)的代码是明智的,这将是{{ 1}}。如果代码处于循环中并且运行数百万次,那么它就会开始产生影响,而其他一个代码可能会更加明智。