Checking if String.scan does not match

A

Alex Allmont

Hi everyone,

I'm extracting 3 words from a string delimited with colons using the follow=
ing approach:

str =3D "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 on=
ly 2 words, e.g. "test:string", the block is not executed.

I need to report an error if the match fails. This could be done like this=
:

str =3D "test:string"
matched =3D false
str.scan(/(.+):(.+):(.+)/) do |a, b, c|
puts a, b, c
matched =3D true
end
if not matched
puts "invalid format"
end

but this is messy. Is there a neater, more ruby-like, approach to this?

Any help is greatly appreciated,
Alex
 
B

Brian Candler

Alex said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top