From: Robert Klemme Date: 2010-12-05T21:50:20+09:00 Subject: Re: Split a string at a certain character On 04.12.2010 23:14, Matt Slay wrote: >> Pick Axe page 70-75: >> >> ruby-1.9.2-head> s = '12.7 AB36' >> => "12.7 AB36" >> ruby-1.9.2-head> pattern = /\A([0-9.]+)\s*([a-zA-Z]{1,2}[0-9]+)\Z/ >> => /\A([0-9.]+)\s*([a-zA-Z]{1,2}[0-9]+)\Z/ >> ruby-1.9.2-head> s.match pattern >> => # >> ruby-1.9.2-head> $1 >> => "12.7" >> ruby-1.9.2-head> $2 >> => "AB36" > Peter!!!! You are *THE* man!!! I actually just bought the 1.9.2 version > of the book for just $10. Regular Expressions are now on page 97 > (Chapter 7). I'm an FoxPro programmer and just beginning my work in > Ruby. > > I threw your pattern and match command into a Controller action in my > Rails app, and guess what.... It works!! > > Here's my code, after just 1 minute of work, thanks to you. (Some > refinements are now needed for stupid user input, but I'll get. > > I'm so excited to see this come to life so easily. The Ruby community is > awesome. > > def create > @conversion = Conversion.new(params[:conversion]) > pattern = /\A([0-9.]+)\s*([a-zA-Z]{1,2}[0-9]+)\Z/ > user_input = @conversion.shaft_size > @size = user_input.match pattern > > respond_to do |format| > format.html { render :show } > end > end > > > Now I can access the @size[1] and @size[2] to get what I need done. > > How many times can I say "Thanks"??? There are a few things to say about this solution though: The float part does not exactly match floating point numbers but it would also match these sequences: 127.0.0.1, 1..10, 4...3 etc. "[0-9]" can be replaced by "\d". Assigning the pattern to a variable and then using that for matching is generally less efficient than directly using the pattern. The pattern "\Z" allows for a newline at the end of the string. This may be OK or not (you can also use #chomp on the input to remove trailing line terminators before handing the input to the method). I would rather go with a combination of Peter's and Josh's solution: def parse(str) if /\A(\d+(?:\.\d+)?)\s*([a-z]{1,2}\d+)\z/i =~ str return Float($1), $2 else raise "Invalid input: %p" % str end end If you need to cope with negative floats and signs in general you can change the initial part to \A([-+]?\d+(?:\.\d+)?) Few notes and explanations: The code does the conversion inside the method which may be desirable or not - depending on your context. I picked Float() for added robustness, it will raise an exception if the matching was flawed (which should not be the case here). I added error checking with exception. Btw, your original description of the sequence is pretty good for direct translation into a regular expression. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/