操纵红宝石中的字符串

时间:2014-01-20 20:10:46

标签: ruby string

我有一组字符串变量,类似于"height_low"。我想使用像gsub或其他东西一样清洁的东西来摆脱下划线和过去的一切。所以它就像"height"。有人有解决方案吗?感谢。

7 个答案:

答案 0 :(得分:3)

试试这个:

strings.map! {|s| s.split('_').first}

答案 1 :(得分:1)

更短的:

my_string.split('_').first

答案 2 :(得分:1)

不可避免的正则表达式答案。 (假设strings是一个字符串数组。)

strings.map! { |s| s[/^.+?(?=_)/] }

答案 3 :(得分:1)

使用str[regexp, capture] → new_str or nil尝试如下:

  

如果提供了Regexp,则返回字符串的匹配部分。如果捕获遵循正则表达式(可能是捕获组索引或名称),则遵循正则表达式,而是返回 MatchData 的组件。

strings.map { |s|  s[/(.*?)_.*$/,1] }

答案 4 :(得分:1)

FWIW,基于String#split的解决方案表现不佳,因为他们必须解析整个字符串并分配一个数组。随着下划线数量的增加,它们的性能会下降。以下表现更好:

string[0, string.index("_") || string.length]

基准测试结果(括号中的下划线数量):

                       user     system      total        real
String#split (0)   0.640000   0.000000   0.640000 (  0.650323)
String#split (1)   0.760000   0.000000   0.760000 (  0.759951)
String#split (9)   2.180000   0.010000   2.190000 (  2.192356)
String#index (0)   0.610000   0.000000   0.610000 (  0.625972)
String#index (1)   0.580000   0.010000   0.590000 (  0.589463)
String#index (9)   0.600000   0.000000   0.600000 (  0.605253)

基准:

strings = ["x", "x_x", "x_x_x_x_x_x_x_x_x_x"]

Benchmark.bm(16) do |bm|
    strings.each do |string|
        bm.report("String#split (#{string.count("_")})") do
            1000000.times { string.split("_").first }
        end
    end
    strings.each do |string|
        bm.report("String#index (#{string.count("_")})") do
            1000000.times { string[0, string.index("_") || string.length] }
        end
    end
end

答案 5 :(得分:0)

如果您正在寻找“像gsub”这样的东西,为什么不使用gsub?

"height_low".gsub(/_.*$/, "") #=> "height"

在我看来,这有点清洁:

"height_low".split('_').first #=> "height"

另一种选择是使用分区:

"height_low".partition("_").first #=> "height"

答案 6 :(得分:0)

学习从搜索与替换的角度思考。搜索和提取您想要的内容通常比搜索和删除您不想要的内容更容易,更快速,更清晰。

考虑一下:

'a_b_c'[/^(.*?)_/, 1] # => "a"

它只查找您想要的内容,即字符串开头的文本,最多_。 <{1}}之前的所有内容都会被捕获并返回。

替补:

_

必须向后看,直到引擎确定不再有'a_b_c'.sub(/_.+$/, '') # => "a" 'a_b_c'.gsub(/_.+$/, '') # => "a" ,然后字符串就会被截断。

这是一个小基准,显示了这会影响事物:

_

同样,搜索会比任何替换更快,所以想想你正在做什么。

“搜索”基于正则表达式的策略如“string_capture”和“look_ahead”的垮台是他们不处理丢失的require 'fruity' compare do string_capture { 'a_b_c'[/^(.*?)_/, 1] } string_sub { 'a_b_c'.sub(/_.+$/, '') } string_gsub { 'a_b_c'.gsub(/_.+$/, '') } look_ahead { 'a_b_c'[/^.+?(?=_)/] } string_index { 'a_b_c'[0, s.index("_") || s.length] } end # >> Running each test 8192 times. Test will take about 1 second. # >> string_index is faster than string_capture by 19.999999999999996% ± 10.0% # >> string_capture is similar to look_ahead # >> look_ahead is faster than string_sub by 70.0% ± 10.0% # >> string_sub is faster than string_gsub by 2.9x ± 0.1 ,所以如果你的字符串是否会有任何疑问_,然后使用“string_index”方法,该方法将回退到使用_来抓取整个字符串。