Portaljacker
Portaljacker

Reputation: 3142

Extract part of string in Ruby

So I'm given a text file containing:

Blade Runner (1982) [117 min] 
Full Metal Jacket (1987) [116 min] 
Monty Python and the Holy Grail (1975) [91 min] 
The Godfather (1972) [175 min]

and have to turn it into this:

Movie name: Blade Runner  
Movie release year: 1982 
Movie length (in mins): 117 

Movie name: Full Metal Jacket  
Movie release year: 1987 
Movie length (in mins): 116 

Movie name: Monty Python and the Holy Grail  
Movie release year: 1975 
Movie length (in mins): 91 

Movie name: The Godfather  
Movie release year: 1972 
Movie length (in mins): 175

First I iterate on each line, then I thought I should iterate on each part of the string, but that's where I get stuck, how do I do that? Do I use regex? How do I save a specific string that matches a regex?

Here's the current shell of the code, it stores the three parts into variables which are used to initialize a movie class who's to_s method prints in the desired format.

I know it's not right in many ways, but that's why I'm asking for help. variable = /regex/ is the line where the variable is assigned the thing captured by the regex and when /regex/ is for when that regex is matched.

class Movie
    def initialize (name, year, length) # constructor
        @name = name
        @year = year
        @length = length
    end

    def to_s    # returns string representation of object
        return "Movie Name: " + @name
            + "\nMovie release year: "
            + @year + "\nMovie Length (in min): "
            + @length + "\n"
    end
end

$movies = []
File.open("movies.txt").each do |line|
  if matches = /(.*)? \((\d+).*?(\d+)/.match(line)
    $movies << Movie.new(matches[1], matches[2], matches[3])
  end
end


for $movie in $movies do #what u got here is not index but the element in the array
    print $movie.to_s
end

Edit:

Fixed version of code, but print loop at end doesn't work.

Edit2: and nownit does. Thanks PeterPeiGuo!

Upvotes: 2

Views: 2412

Answers (3)

勿绮语
勿绮语

Reputation: 9320

m = /(.*)? \((\d+).*?(\d+)/.match("Blade Runner (1982) [117 min]")

Upvotes: 3

bkempner
bkempner

Reputation: 652

# create string containing list of movies (numerous ways to load this data)
movie = <<-MOV
Blade Runner (1982) [117 min] 
Full Metal Jacket (1987) [116 min] 
Monty Python and the Holy Grail (1975) [91 min] 
The Godfather (1972) [175 min]
<<-MOV

# split movies into lines, then iterate over each line and do some regex
# to extract relavent data (name, year, runtime)
data = movies.split("\n").map do |s| 
  s.scan(/([\w\s]+)\ \((\d+)\)\ \[(\d+)\ min\]/).flatten }
end
# => [['Blade Runner', '1982', '117'], ... ]

# iterate over data, output in desired format.
data.each do |data| 
  puts "Movie name: #{data[0]}\nMovie release year: #{data[1]}\nMovie length: (in mins): #{data[2]}\n\n" }
end
# outputs in format you specified

Upvotes: 2

rabusmar
rabusmar

Reputation: 4143

You can do something like this:

$movies = []
File.open("movies.txt").each do |line|
  if matches = /^(.*)\((\d+)\) \[(\d+)\smin\]/.match(line)
    $movies << Movie.new(matches[1], matches[2], matches[3])
  end
end

Upvotes: 2

Related Questions