我有一组字符串变量,类似于"height_low"
。我想使用像gsub或其他东西一样清洁的东西来摆脱下划线和过去的一切。所以它就像"height"
。有人有解决方案吗?感谢。
答案 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”方法,该方法将回退到使用_
来抓取整个字符串。