Splitting string into array keeping delimiters

Hi, I’ve been playing Ruby for a few months now.
Yesterday I came across an interesting problem.
If I have this string:
abcd1234abc123
Now I want to separate the digit group with the non-digit group into an
array like this [“abcd”,1234,“abc”,123]. It’s like re.split in Python.
How can I do it in Ruby with the least lines of code possible?
‘abcd1234abc123’.split(/\d+/) only returns [“abcd”,“abc”]
Thank you in advance

Gary C40 wrote:

If I have this string:
abcd1234abc123
Now I want to separate the digit group with the non-digit group into an
array like this [“abcd”,1234,“abc”,123]. It’s like re.split in Python.
How can I do it in Ruby with the least lines of code possible?
‘abcd1234abc123’.split(/\d+/) only returns [“abcd”,“abc”]

If the regex has capturing groups you’ll get those in the array as well.
‘abcd1234abc123’.split(/(\d+)/) #=> [“abcd”, “1234”, “abc”, “123”]

If you need the numbers as integers, you could use something like:
‘abcd1234abc123’.scan(/(\D+)(\d+)?/).map {|nd,d| [nd,d.to_i]}
#=> [[“abcd”, 1234], [“abc”, 123]]
(Maybe add flatten and compact)

or

res=[]
‘abcd1234abc123’.scan(/(\D+)(\d+)?/) do
res << $1
res << $2.to_i if $2
end
res #=> [“abcd”, 1234, “abc”, 123]

HTH,
Sebastian

On Dec 15, 2007, at 4:39 PM, Sebastian H. wrote:

If the regex has capturing groups you’ll get those in the array as
well.
‘abcd1234abc123’.split(/(\d+)/) #=> [“abcd”, “1234”, “abc”, “123”]

If you need the numbers as integers, you could use something like:
‘abcd1234abc123’.scan(/(\D+)(\d+)?/).map {|nd,d| [nd,d.to_i]}
#=> [[“abcd”, 1234], [“abc”, 123]]
(Maybe add flatten and compact)

Just another one:

‘abcd1234abc123’.scan(/\D+|\d+/) # [“abcd”, “1234”, “abc”, “123”]

– fxn

On Dec 15, 8:47 am, Xavier N. [email protected] wrote:

Python.
(Maybe add flatten and compact)

Just another one:

‘abcd1234abc123’.scan(/\D+|\d+/) # [“abcd”, “1234”, “abc”, “123”]

And another, from 1.9:

irb(main):004:0> str.split /(?<=\D)(?=\d)|(?<=\d)(?=\D)/
=> [“abcd”, “1234”, “abc”, “123”]

Wow, there sure are more than one way to solve a problem in Ruby.
Thanks for your help, I’ll try them out :wink:

Phrogz wrote:

On Dec 15, 8:47 am, Xavier N. [email protected] wrote:
And another, from 1.9:

Yet another, after “gem install facets” and require “facets/string”:

‘abcd1234abc123’.shatter(/\d+/)

On Dec 15, 9:16 am, Gary C40 [email protected] wrote:

Posted viahttp://www.ruby-forum.com/.
And the highly esoteric version…

n = [[]]
s = [[]]
‘abcd1234abc123’.each_byte { | x |
if (47…57).include?(x)
then s << []; n.last << x
else n << []; s.last << x
end
}
n = n.reject { | x | x.empty? }.map { | x |
x.map {| y | y.chr }.join(“”).to_i }
s = s.reject { | x | x.empty? }.map { | x |
x.map { | y | y.chr }.join(“”) }
result = if n.length > s.length
then n.zip(s).flatten.compact
else s.zip(n).flatten.compact
end
p result # => [“abcd”, 1234, “abc”, 123]

Regards,
Jordan