user3214044
user3214044

Reputation: 83

how to Split and get data in ruby

I am newbie in ruby. Now, I have problem about text splitting by ruby programming.

My text is like

AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700|DD:0.71:1700:2010|EE:1.00:2070:2390

So I need result to (process until end of text)

AA 0.88
BB 0.82
CC 0.77
DD 0.71
EE 1.00

How to coding it. Now I can only split by "|".

Best regard.

Upvotes: 1

Views: 104

Answers (4)

hirolau
hirolau

Reputation: 13921

And here, just for reference, is a regexp version:

s = 'AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700|DD:0.71:1700:2010|EE:1.00:2070:2390'
p s.scan /(?:\||\A)([^:]+):([^:]+)/
# => [["AA", "0.88"], ["BB", "0.82"], ["CC", "0.77"], ["DD", "0.71"], ["EE", "1.00"]]

The code is shorter but much harder to read and debug. Use the other answers before this one!

Edit:

And here is the same regexp with some comments:

s.scan %r{
  (?: \| | \A) # Look for start of string (\A) or '|' (\|) but do not include in capture (?:)
  ([^:]+)      # Look for and capture one or more characters that are not ':'
  :            # Look for but do not capture a ':', Not captured as line is not in parenthesis.
  ([^:]+)      # Repeat second line.
}x # x modifies the regexp to allow comments.

Upvotes: 1

Cary Swoveland
Cary Swoveland

Reputation: 110755

Using gsub and regex:

str = "AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700|" +
      "DD:0.71:1700:2010|EE:1.00:2070:2390"

puts str.gsub(':',' ').scan(/(([A-Z])\2 \d\.\d\d)/).map(&:first)

AA 0.88
BB 0.82
CC 0.77
DD 0.71
EE 1.00

These are the steps:

s1 = str.gsub(':',' ')
  # => "AA 0.88 320 800|BB 0.82 1040 1330|CC 0.77 1330 1700|
       DD 0.71 1700 2010|EE 1.00 2070 2390" (broken for display)
s2 = s1.scan(/(([A-Z])\2 \d\.\d\d)/)
  # => [["AA 0.88", "A"], ["BB 0.82", "B"], ["CC 0.77", "C"],
        ["DD 0.71", "D"], ["EE 1.00", "E"]] 
s3 = s2.map(&:first)
  # => ["AA 0.88", "BB 0.82", "CC 0.77", "DD 0.71", "EE 1.00"] 

In the regex, /(...)/ and ([A-Z]) are the first and second capture groups, respectively. \2 equals what is captured by the second group, so `([A-Z])\2 requires that the same two capital letters appear together (e.g., 'CC').

Upvotes: 0

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121020

s = 'AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700'
s.split('|').map { |item| # produces an array and remaps it
  s1, s2, * = item.split(':')
  puts "#{s1} #{s2}"
  [s1, s2]
}

Hope it helps.

Upvotes: 0

falsetru
falsetru

Reputation: 369494

Use String#split:

s = 'AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700|DD:0.71:1700:2010|EE:1.00:2070:2390'
s.split('|').each do |substring|
  name, num, * = substring.split(':')
  puts "#{name} #{num}"
end

output:

AA 0.88
BB 0.82
CC 0.77
DD 0.71
EE 1.00

Upvotes: 4

Related Questions