Splitting string into array keeping delimiters

Discussion in 'Ruby' started by Gary C40, Dec 15, 2007.

  1. Gary C40

    Gary C40 Guest

    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
    --
    Posted via http://www.ruby-forum.com/.
    Gary C40, Dec 15, 2007
    #1
    1. Advertising

  2. 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
    --
    Jabber:
    ICQ: 205544826
    Sebastian Hungerecker, Dec 15, 2007
    #2
    1. Advertising

  3. Gary C40

    Xavier Noria Guest

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

    > 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)


    Just another one:

    'abcd1234abc123'.scan(/\D+|\d+/) # ["abcd", "1234", "abc", "123"]

    -- fxn
    Xavier Noria, Dec 15, 2007
    #3
  4. Gary C40

    Phrogz Guest

    On Dec 15, 8:47 am, Xavier Noria <> wrote:
    > On Dec 15, 2007, at 4:39 PM, Sebastian Hungerecker wrote:
    >
    >
    >
    > > 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)

    >
    > 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"]
    Phrogz, Dec 15, 2007
    #4
  5. Phrogz wrote:
    > On Dec 15, 8:47 am, Xavier Noria <> wrote:
    > And another, from 1.9:


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

    'abcd1234abc123'.shatter(/\d+/)
    Clifford Heath, Dec 15, 2007
    #5
  6. Gary C40

    Gary C40 Guest

    Wow, there sure are more than one way to solve a problem in Ruby.
    Thanks for your help, I'll try them out ;)
    --
    Posted via http://www.ruby-forum.com/.
    Gary C40, Dec 16, 2007
    #6
  7. Gary C40

    MonkeeSage Guest

    On Dec 15, 9:16 am, Gary C40 <> wrote:
    > 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
    > --
    > 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
    MonkeeSage, Dec 16, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page