英文:
How to split a string while conserving split elements as empty strings?
问题
"我正在尝试拆分一个字符串,以便已被“拆分”的元素被保留为空字符串,例如字符串"abaca"
,我需要结果为["", "b", "", "c", ""]
,或者字符串"xzxzxz"
的结果为["x","","x","","x",""]
,简单地添加空元素不起作用,因为我不知道拆分的元素可能存在在字符串的开头或结尾。
我尝试过使用interspersing,然而,我找到的每种方法都导致错误或不是我想要的。除此之外,我没有找到其他可以帮助的方法。"
英文:
I'm trying to split a string so that elements that have been "split" are conserved as empty strings, for example with a string of "abaca"
I need the result to be ["", "b", "", "c", ""]
or a string of "xzxzxz"
to result in ["x","","x","","x",""]
Simply adding empty elements does not work, as I do not know whether the element I split with may exist at the start or end of the string.
I've tried to use interspersing, however every method I've found for that has led to either an error or not what I wanted. Apart from that, I have not found anything else that could help.
答案1
得分: 2
For this problem, it's more convenient to match a regular expression than it is to split on one.
def doit(str, spl)
sp = Regexp.escape(spl)
str.gsub(/#{sp}|.+?(?=#{sp}|$)/).map { |s| s == spl ? " " : s }
end
Here's an example of the steps.
str = 'iswasistoday'
spl = 'is'
I'm providing the translated code, but I won't address further questions about it.
英文:
For this problem it's more convenient to match a regular expression than it is to split on one.
def doit(str, spl)
sp = Regexp.escape(spl)
str.gsub(/#{sp}|.+?(?=#{sp}|$)/).map { |s| s == spl ? " " : s }
end
doit('abaca', 'a') #=> [" ", "b", " ", "c", " "]
doit('xzxzxz', 'z') #=> ["x", " ", "x", " ", "x", " "]
doit('nowiswasistoday', 'is') #=> ["now", " ", "was", " ", "today"]
doit('iswasistoday', 'is') #=> [" ", "was", " ", "today"]
doit('i?si?s', '?') #=> ["i", " ", "si", " ", "s"]
Here's an example of the steps.
str = 'iswasistoday'
spl = 'is'
<!-->
sp = Regexp.escape(spl)
#=> "is"
Here I am using Regexp.escape to escape characters of spl
that have special meaning in regular expressions. We see that sp
is the same as spl
in this case, but in the last example above ?
has a special meaning in regular expressions (namely, to make matches optional or to match as few characters as possible). In that case Regexp.escape('?') #=> "\\?"
. Continuing,
rgx = /#{sp}|.+?(?=#{sp}|$)/
#=> /is|.+?(?=is|$)/
<!-->
enum = str.gsub(rgx)
#=> #<Enumerator: "iswasistoday":gsub(/is|.+?(?=is|$)/)>
Here I am using the form of String#gsub that takes a single argument and no block, returning an enumerator that generates matches of it's argument, here a regular expression. We can see the matches that will be generated by converting this enumerator to an array.
enum.to_a
#=> ["is", "was", "is", "today"]
The last step follows.
enum.map { |s| s == spl ? " " : s }
#=> [" ", "was", " ", "today"]
The regular expression has the following elements.
/
#{sp} match the value of the variable sp
| or
.+ match one or more characters other than line terminators
? make previous match relunctant, matching as few characters as possible
(?= begin a positive lookahead
#{sp} match the value of the variable sp
| or
$ match the end of the string
) end the positive lookahead
/
答案2
得分: 1
You could use each_char to iterate each character, then map them yourself.
'abaca'.each_char.map { |c| c.eql?('a') ? ' ' : c }
=> [" ", "b", " ", "c", " "]
'xzxzxz'.each_char.map { |c| c.eql?('z') ? ' ' : c }
=> ["x", " ", "x", " ", "x", " "]
英文:
You could use each_char to iterate each character, then map them yourself.
'abaca'.each_char.map { |c| c.eql?('a') ? ' ' : c }
=> [" ", "b", " ", "c", " "]
'xzxzxz'.each_char.map { |c| c.eql?('z') ? ' ' : c }
=> ["x", " ", "x", " ", "x", " "]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论