我正在try 拆分一个字符串,以便将已"拆分"的元素保存为空字符串,例如,对于字符串"abaca"
,我需要结果为["", "b", "", "c", ""]
或字符串"xzxzxz"
才能得到["x","","x","","x",""]
.简单地添加空元素是不起作用的,因为我不知道与我拆分的元素是否存在于字符串的开头或结尾.
我试着使用散布,然而我找到的每一种方法要么导致错误,要么不是我想要的.除此之外,我没有发现任何其他可能有帮助的东西.
我正在try 拆分一个字符串,以便将已"拆分"的元素保存为空字符串,例如,对于字符串"abaca"
,我需要结果为["", "b", "", "c", ""]
或字符串"xzxzxz"
才能得到["x","","x","","x",""]
.简单地添加空元素是不起作用的,因为我不知道与我拆分的元素是否存在于字符串的开头或结尾.
我试着使用散布,然而我找到的每一种方法要么导致错误,要么不是我想要的.除此之外,我没有发现任何其他可能有帮助的东西.
对于这个问题,匹配正则表达式比拆分一个正则表达式更方便.
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"]
以下是这些步骤的一个示例.
str = 'iswasistoday'
spl = 'is'
sp = Regexp.escape(spl)
#=> "is"
在这里,我使用Regexp.escape来转义spl
中在正则表达式中具有特殊意义的字符.我们看到,在本例中,sp
与spl
相同,但在上面的最后一个示例中,?
在正则表达式中有特殊的含义(即,使匹配成为可选的或匹配尽可能少的字符).那样的话,Regexp.escape('?') #=> "\\?"
美元.继续,
rgx = /#{sp}|.+?(?=#{sp}|$)/
#=> /is|.+?(?=is|$)/
enum = str.gsub(rgx)
#=> #<Enumerator: "iswasistoday":gsub(/is|.+?(?=is|$)/)>
在这里,我使用String#gsub的形式,它只接受一个参数,没有块,返回一个枚举数,该枚举器生成与它的参数匹配的参数,这里是一个正则表达式.我们可以看到通过将此枚举数转换为数组而生成的匹配项.
enum.to_a
#=> ["is", "was", "is", "today"]
接下来是最后一步.
enum.map { |s| s == spl ? " " : s }
#=> [" ", "was", " ", "today"]
正则表达式具有以下元素.
/
#{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
/