Ruby:在边界上拆分字符串

Ruby:在边界上拆分字符串,ruby,regex,Ruby,Regex,我有一个任意字符的字符串,其中一些是数字。我想把字符串分成由数字和非数字组成的字段。例如,如果我的字符串的值为'abc34d-f9',我希望得到一个数组 ['abc','34','d-f','9'] 我就快到了,用“向后看”和“向前看”的表达方式: s.split(/( (?<=\D)(?=\d) | (?<=\d)(?=\D) )/x) 当然,从数组中过滤掉空字符串是很简单的。我只是想知道:为什么要得到它们,如何才能做得更好?使用函数返回匹配字符串的数组 > 'abc34

我有一个任意字符的字符串,其中一些是数字。我想把字符串分成由数字和非数字组成的字段。例如,如果我的字符串的值为'abc34d-f9',我希望得到一个数组

['abc','34','d-f','9']
我就快到了,用“向后看”和“向前看”的表达方式:

s.split(/( (?<=\D)(?=\d) | (?<=\d)(?=\D) )/x)
当然,从数组中过滤掉空字符串是很简单的。我只是想知道:为什么要得到它们,如何才能做得更好?

使用函数返回匹配字符串的数组

> 'abc34d-f9'.scan(/\D+|\d+/)
=> ["abc", "34", "d-f", "9"]
\D+
匹配一个或多个非数字字符,其中
\D+
匹配一个或多个数字字符

如果删除捕获组,您的正则表达式也可以正常工作。因为捕获组还会将分隔符(输入字符串拆分的边界)返回到最终输出

> 'abc34d-f9'.split(/(?<=\D)(?=\d)|(?<=\d)(?=\D)/)
=> ["abc", "34", "d-f", "9"]
> 'abc34d-f9'.split(/ (?<=\D)(?=\d) | (?<=\d)(?=\D) /x)
=> ["abc", "34", "d-f", "9"]

虽然我更喜欢@AvinashRaj的解决方案,但尝试找到其他方法总是很有趣(有时也很有启发性):

str = 'abc34d-f9'

a = str.split(/(\d+)/)    #=> ["abc", "34", "d-f", "9"] 
a.shift if a.first.empty? #=> nil
a                         #=> ["abc", "34", "d-f", "9"] 

a = str.split(/(\D+)/)    #=> ["", "abc", "34", "d-f", "9"] 
a.shift if a.first.empty? #=> "" 
a                         #=> ["abc", "34", "d-f", "9"] 

str.each_char.chunk { |c| !!(c =~ /\d/) }.map { |_,a| a.join }
                          #=> ["abc", "34", "d-f", "9"] 

str[1..-1].each_char.with_object([str[0]]) { |c,a|
  ((c + a.last[0]) =~ /\d{2}|\D{2}/) ? a.last << c : a << c }
                          #=> ["abc", "34", "d-f", "9"] 

(Ruby 2.2)
str.each_char.slice_when { |a,b| (a+b) =~ /\d\D|\D\d/ }.map(&:join)
                          #=> ["abc", "34", "d-f", "9"] 
str='abc34d-f9'
a=str.split(/(\d+/)#=>[“abc”,“34”,“d-f”,“9”]
a、 如果a.first.empty?#=>nil,则移位
a#=>[“abc”、“34”、“d-f”、“9”]
a=str.split(/(\D+/)#=>,“abc”,“34”,“D-f”,“9”]
a、 如果a.first.empty?#=>“”
a#=>[“abc”、“34”、“d-f”、“9”]
str.each|char.chunk{| c |!!(c=~/\d/)}.map{| |,a | a.join}
#=>[“abc”,“34”,“d-f”,“9”]
str[1..-1]。每个_字符与_对象([str[0]]){c,一个|
((c+a.last[0])=~/\d{2}|\d{2}/)?a.last[“abc”,“34”,“d-f”,“9”]
str = 'abc34d-f9'

a = str.split(/(\d+)/)    #=> ["abc", "34", "d-f", "9"] 
a.shift if a.first.empty? #=> nil
a                         #=> ["abc", "34", "d-f", "9"] 

a = str.split(/(\D+)/)    #=> ["", "abc", "34", "d-f", "9"] 
a.shift if a.first.empty? #=> "" 
a                         #=> ["abc", "34", "d-f", "9"] 

str.each_char.chunk { |c| !!(c =~ /\d/) }.map { |_,a| a.join }
                          #=> ["abc", "34", "d-f", "9"] 

str[1..-1].each_char.with_object([str[0]]) { |c,a|
  ((c + a.last[0]) =~ /\d{2}|\D{2}/) ? a.last << c : a << c }
                          #=> ["abc", "34", "d-f", "9"] 

(Ruby 2.2)
str.each_char.slice_when { |a,b| (a+b) =~ /\d\D|\D\d/ }.map(&:join)
                          #=> ["abc", "34", "d-f", "9"]