Ruby 删除以特定字符开头的所有子字符串
Ruby remove all substrings that begin with specific character
我想删除字符串中以井号开头并以 space 结尾或位于字符串末尾的所有子字符串。我有一个有效的解决方案,但我想知道是否有更有效(或同样有效但不那么冗长)的方法。
比如我想把"leo is #confused about #ruby #gsub"
变成"#confused #ruby #gsub"
.
这是我目前的解决方案,其中涉及数组和减法。
strip_spaces = str.gsub(/\s+/, ' ').strip()
=> "leo is #confused about #ruby #gsub"
all_strings = strip_spaces.split(" ").to_a
=> ["leo", "is", "#confused", "about", "#ruby", "#gsub"]
non_hashtag_strings = strip_spaces.gsub(/(?:#(\w+))/) {""}.split(" ").to_a
=> ["leo", "is", "about"]
hashtag_strings = (all_strings - non_hashtag_strings).join(" ")
=> "#confused #ruby #gsub"
老实说,既然我写完了这个问题,我通过 research/experimentation 学到了一些东西,并且对这种数组方法更加熟悉。但我仍然想知道是否有人可以推荐改进。
你可以试试这个
string.split(' ').select { |e| e.start_with?("#") }.join(' ')
说明
split
- 根据分隔符将字符串分成子字符串数组,在本例中为 space
select
- 用于过滤匹配传入表达式
的数组
|e| e.start_with?("#")
- 仅查找以井号开头的子字符串
join(' ')
- 用于将数组转换回字符串
我会这样做:
string = "leo is #confused about #ruby #gsub"
#=> "leo is #confused about #ruby #gsub"
string.split.select { |word| word.start_with?('#') }.join(' ')
#=> "#confused #ruby #gsub"
仅正则表达式解决方案
string = "leo is #confused about #ruby #gsub"
string.scan(/#\w+/)
# => ["#confused", "#ruby", "#gsub"]
如果您希望在单词中包含 #
符号,则正则表达式稍微复杂:
string = "leo is #confused ab#out #ruby #gsub"
string.scan(/(?<=\s)#\w+/)
# => ["#confused", "#ruby", "#gsub"]
总是有更多方法给猫剥皮
s = "leo is #confused about #ruby #gsub"
#sub all the words that do not start with a #
s.gsub(/(?<=^|\s)#\w+\s?/,'')
#=> "#confused #ruby #gsub"
#split to Array and grab all the strings that start with #
s.split.grep(/\A#/).join(' ')
#=> "#confused #ruby #gsub"
#split to Array and separate them into 2 groups
starts_with_hash,others = s.split.partition {|e| e.start_with?('#') }
#=>[["#confused", "#ruby", "#gsub"], ["leo", "is", "about"]]
starts_with_hash.join(' ')
#=> "#confused #ruby #gsub"
fruity
提供的这些和其他答案的基准测试
require 'fruity'
def split_start_with(s)
s.split.select {|e| e.start_with?("#")}.join(' ')
end
def with_scan(s)
s.scan(/#\w+/).join(' ')
end
def with_gsub(s)
s.gsub(/(?<=^|\s)#\w+\s?/,'')
end
def split_grep(s)
s.split.grep(/\A#/).join(' ')
end
str = "This is a reasonable string #withhashtags where I want to #test multiple #stringparsing #methods for separating and joinging #hastagstrings together for #speed"
compare do
split_start_with_test {split_start_with(str)}
with_scan_test {with_scan(str)}
with_gsub_test {with_gsub(str)}
split_grep_test {split_grep(str)}
end
结果:
Running each test 262144 times. Test will take about 5 minutes.
split_start_with_test is similar to with_scan_test
with_scan_test is faster than with_gsub_test by 60.00000000000001% ± 1.0%
with_gsub_test is faster than split_grep_test by 30.000000000000004% ± 1.0%
我想删除字符串中以井号开头并以 space 结尾或位于字符串末尾的所有子字符串。我有一个有效的解决方案,但我想知道是否有更有效(或同样有效但不那么冗长)的方法。
比如我想把"leo is #confused about #ruby #gsub"
变成"#confused #ruby #gsub"
.
这是我目前的解决方案,其中涉及数组和减法。
strip_spaces = str.gsub(/\s+/, ' ').strip()
=> "leo is #confused about #ruby #gsub"
all_strings = strip_spaces.split(" ").to_a
=> ["leo", "is", "#confused", "about", "#ruby", "#gsub"]
non_hashtag_strings = strip_spaces.gsub(/(?:#(\w+))/) {""}.split(" ").to_a
=> ["leo", "is", "about"]
hashtag_strings = (all_strings - non_hashtag_strings).join(" ")
=> "#confused #ruby #gsub"
老实说,既然我写完了这个问题,我通过 research/experimentation 学到了一些东西,并且对这种数组方法更加熟悉。但我仍然想知道是否有人可以推荐改进。
你可以试试这个
string.split(' ').select { |e| e.start_with?("#") }.join(' ')
说明
split
- 根据分隔符将字符串分成子字符串数组,在本例中为 space
select
- 用于过滤匹配传入表达式
|e| e.start_with?("#")
- 仅查找以井号开头的子字符串
join(' ')
- 用于将数组转换回字符串
我会这样做:
string = "leo is #confused about #ruby #gsub"
#=> "leo is #confused about #ruby #gsub"
string.split.select { |word| word.start_with?('#') }.join(' ')
#=> "#confused #ruby #gsub"
仅正则表达式解决方案
string = "leo is #confused about #ruby #gsub"
string.scan(/#\w+/)
# => ["#confused", "#ruby", "#gsub"]
如果您希望在单词中包含 #
符号,则正则表达式稍微复杂:
string = "leo is #confused ab#out #ruby #gsub"
string.scan(/(?<=\s)#\w+/)
# => ["#confused", "#ruby", "#gsub"]
总是有更多方法给猫剥皮
s = "leo is #confused about #ruby #gsub"
#sub all the words that do not start with a #
s.gsub(/(?<=^|\s)#\w+\s?/,'')
#=> "#confused #ruby #gsub"
#split to Array and grab all the strings that start with #
s.split.grep(/\A#/).join(' ')
#=> "#confused #ruby #gsub"
#split to Array and separate them into 2 groups
starts_with_hash,others = s.split.partition {|e| e.start_with?('#') }
#=>[["#confused", "#ruby", "#gsub"], ["leo", "is", "about"]]
starts_with_hash.join(' ')
#=> "#confused #ruby #gsub"
fruity
require 'fruity'
def split_start_with(s)
s.split.select {|e| e.start_with?("#")}.join(' ')
end
def with_scan(s)
s.scan(/#\w+/).join(' ')
end
def with_gsub(s)
s.gsub(/(?<=^|\s)#\w+\s?/,'')
end
def split_grep(s)
s.split.grep(/\A#/).join(' ')
end
str = "This is a reasonable string #withhashtags where I want to #test multiple #stringparsing #methods for separating and joinging #hastagstrings together for #speed"
compare do
split_start_with_test {split_start_with(str)}
with_scan_test {with_scan(str)}
with_gsub_test {with_gsub(str)}
split_grep_test {split_grep(str)}
end
结果:
Running each test 262144 times. Test will take about 5 minutes.
split_start_with_test is similar to with_scan_test
with_scan_test is faster than with_gsub_test by 60.00000000000001% ± 1.0%
with_gsub_test is faster than split_grep_test by 30.000000000000004% ± 1.0%