Value of $1is retained

Hi
I am using regexp in a loop to extract a value from a
string. I have noticed that when string is nil $1 keeps its
old value, which means that the expression after regexp
does not get the correct value (which should be nil). The
code looks like this

(0…key_colnames.length-1).each do |i|
person_data[key_colnames[i]] =~ /"?([\w-: ]*)"?/

assigning $1 to something

end

Shouldn’t the $-variables be reset after each regexp? Or is
it a better way to do this?

/Anders V.
http://www.vesterberg.se

On 8/8/06, Anders V. [email protected] wrote:

assigning $1 to something

end

Shouldn’t the $-variables be reset after each regexp? Or is
it a better way to do this?

/Anders V.
http://www.vesterberg.se

The problem is in your regex. It will match a word containing hyphens
or :
but it will also match an empty string!

a = /"?([\w-:])"?/
=>
/"?([\w-:]
)"?/

“This is a String” =~ a
=>
0

$1
=>
“This”

“” =~ a
=>
0

$1
=>
“”

“$12dc” =~ a
=>
0

$1
=> “”

Without knowing very much about the requirements of your regex, you need
to
replace the * wildcard ( zero or more ) with + (one or more)

a = /"?([\w-:]+)"?/
=>
/"?([\w-:]+)"?/

“This is a String” =~ a
=>
0

$1
=>
“This”

“” =~ a
=>
nil

$1
=>
nil

“$12dc” =~ a
=>
1

$1
=> “12dc”

Nils as you would expect. You could also make the first line it a touch
more rubyish :wink:

key_colnames.each do |key|
person_data[key] =~ /"?([\w-:])"/

do your thing with $1

end

Anders V. wrote:

end

Shouldn’t the $-variables be reset after each regexp? Or is
it a better way to do this?

I know this doesn’t answer your question as to why it works that way,
but you could instead write:

(0…key_colnames.length-1).each do |i|
if person_data[key_colnames[i]] =~ /"?([\w-: ]*)"?/
# assigning $1 to something
end
end

or even:

(0…key_colnames.length-1).each do |i|
myvar = (person_data[key_colnames[i]] =~ /"?([\w-: ]*)"?/) ?
$1 :
nil
end

Incidentally, what version of Ruby are you using? I was unable to
reproduce this behavior on Ruby 1.8.4 on Windows. This sample program:

“boom” =~ /(o)/
puts “$1 = #{$1.inspect}”

“boom” =~ /(a)/
puts “$1 = #{$1.inspect}”

“boom” =~ /(o)/
puts “$1 = #{$1.inspect}”

yields this output:

$1 = “o”
$1 = nil
$1 = “o”

Hi –

On Tue, 8 Aug 2006, Anders V. wrote:

end

Shouldn’t the $-variables be reset after each regexp? Or is
it a better way to do this?

If you’re calling =~ on nil, no match operation takes place.
Object#=~ returns false, and NilClass doesn’t override it.

David