1

I have files that have a bunch of lines containing text and numbers. The text in each file stays the same, but the numbers change. (This is running data, so the lines are things like "- Active Duration 28:19, - Total distance 3.66mi.", etc.)

What I want to do is locate the individual numbers in these lines, then create my own output, such as: "Ran #{distance} in #{time}"

I'm able to locate these numbers in the lines using regular expressions, but I cannot figure out how to then take those values and make them into their own strings. I'm not even sure regex is the right approach. I've been running things like this:

if line =~/\d*\.\d*/
found completed = true

But then I'm not sure what comes next.

I hope I'm being clear—and thanks in advance for your help.

1
  • can you post an example string? Commented Jun 19, 2013 at 22:39

3 Answers 3

2

You can use regex in the element reference to get the number data. For example:

2.0.0-p0 :010 > distance = line[/\d*\.\d*/]
=> "3.66" 
2.0.0-p0 :011 > time = line[/\d*:\d*/]
 => "28:19" 
2.0.0-p0 :012 > puts "Ran #{distance} in #{time}"
Ran 3.66 in 28:19
 => nil
Sign up to request clarification or add additional context in comments.

4 Comments

That looks really promising. Does it require anything? Right now I'm getting 'undefined local variable or method `line' for main:Object (NameError)'
Got it. Elegant and effective. Thanks!
I'd prefer line[/\d+\.\d*/], line[/\d+:\d+/] in scanning the only occurrence of a pattern.
I like Arie's addition, that really smoothes things out.
1

You can do that:

rawlines = <<EOF
- Active Duration 28:19, - Total distance 3.66mi.
- Active Duration 25:12, - Total distance 3.66mi.
- Active Duration 24:10, - Total distance 3.66mi.
- Active Duration 28:21, - Total distance 3.66mi.
- Active Duration 27:19, - Total distance 3.66mi.
EOF

rawlines.scan(/Active Duration (\d++:\d++), - Total distance (\d++(?>\.\d++)?)/) do |dur, dist|
  puts "Ran #{dist} in #{dur}\n"
end

Comments

1

Updated answer to show iteration over file.

I put the results into a hash so that key-value pairs could be utilised for the manipulation of the data. New keys could be added for the unit of measurement, etc.

runData_20130620.txt
-Active Duration 09.87, -Total Distance 100.0m
-Active Duration 15:19, -Total Distance 4.98km
-Active Duration 03:00, -Total Distance 1.0mile
-Active Duration 21:14, -Total Distance 3.68, -Sweat Produced 5.99Gallons
-Active Duration 22:31, -Total Distance 3.65mi

Code

File.foreach("runData_20130620.txt") do |line|

    # Create hash, parsing string with regex pattern
    runData = Hash[*line.scan(/([^, \-]\D*) (\d*[.:]\d*)/).to_a.flatten]

    # This will convert the string keys to symbols, replacing white-space with 
    # underscores and downcasing

    runData = Hash[runData.map { |k,v|
                        [k.gsub(/\s+/, "_").downcase.to_sym, v] }] 

    # display results
    #runData.each { |k,v| puts "#{k} ** #{v}" }

    # display using hash symbol access...
    puts "\nRan a distance of #{ runData[:total_distance]} in
                                               runData[:active_duration]} "
    puts "Man, I am unfit!" if runData[:sweat_produced]
end

Results

Ran a distance of 100.0 in 09.87

Ran a distance of 4.98 in 15:19

Ran a distance of 1.0 in 03:00

Ran a distance of 3.68 in 21:14
Man, I am unfit!

Ran a distance of 3.65 in 22:31

5 Comments

You would need to modify the regex patterns - I tidied the data slightly first
Interesting—looks great! But how could I set this up as a script to read lines in a file? For example, "myData" is always changing, and I don't want to have to input it all by hand.
That shouldn't be too difficult using regular constructs. Does your file have a specified format i.e. is every line in the file the same structure? @craigeley
Each file contains lines such as: - Active Duration 28:19 - Total Distance 3.66 mi. etc. etc.
There's always more than one way to skin a cat. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.