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 Vesterberg
http://www.vesterberg.se

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 Vesterberg
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

···

On 8/8/06, Anders Vesterberg <anders1@vesdakon.se> wrote:

Anders Vesterberg wrote:

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?

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 Vesterberg wrote:

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?

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

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
   ----> SEE SPECIAL DEAL FOR RUBY/RAILS USERS GROUPS! <-----
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
Ruby for Rails => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.