Alex Allmont wrote:
> I'm extracting 3 words from a string delimited with colons using the 
> following approach:
> 
>   str = "test:string:here"
>   str.scan(/(.+):(.+):(.+)/) do |a, b, c|
>     puts a, b, c
>   end
> 
> This works fine if all 3 words are present but if you pass a string with 
> only 2 words, e.g. "test:string", the block is not executed.
> 
> I need to report an error if the match fails.

scan is the wrong tool here, because it is intended to match the pattern 
multiple times in the source string. I think all you want is a basic 
regexp match:

  str = "test:string:here"
  if /\A(.+):(.+):(.+)\z/ =~ str
    puts $1, $2, $3
  else
    puts "invalid format"
  end

Alternatively written as

  case str
  when /\A(.+):(.+):(.+)\z/
    puts $1, $2, $3
  else
    puts "invalid format"
  end

which is useful when there are several different patterns to match 
against the same string.

Beware lines which contain more than 2 colons, because . matches colons 
as well as non-colons. For proper validation you probably want

  /\A([^:]+):([^:]+):([^:]+)\z/

Note that . doesn't match newline. If str may legitimately end with \n, 
but you don't want to capture the \n in $3, then use \Z instead of \z.

If you are 100% positive that str doesn't contain more than one line 
then you can use ^ and $ instead of \A and \Z
-- 
Posted via http://www.ruby-forum.com/.