In article <200306140802.h5E82tm10133 / moulon.inra.fr>,
ts  <decoux / moulon.inra.fr> wrote:
>>>>>> "M" == Mike Stok <mike / ratdog.stok.co.uk> writes:

  [Mike grumbles about constructing regexes:-)]

> Well, this is this case

  [Guy fixes it with a minimal patch]

Excellent, I was thinking about the way regexes/regexps were constructed
in REXML, and then saw http://www.perl.com/pub/a/2003/06/06/regexps.html
..  It seems awkward to me to use strings to interpolate into a regex,
especially when you get into counting backslashes to account for the
double interpolation if you say something lke

  space = '[ \\t]'                      # vs. space = /[ \t]/
  if foo =~ /bar #{space} bax/x

Your patch allows my test case to work and doesn't seem to break
anything else.

I think it would be good if this made it into 1.8.

Thanks (again :-)

Mike

Test session:

[mike@ratdog tmp]$ ruby regex.rb
Loaded suite regex
Started
......
Finished in 0.001459 seconds.
 
5 tests, 13 assertions, 0 failures, 0 errors
[mike@ratdog tmp]$ cat regex.rb
#!/usr/bin/env ruby

require 'test/unit'

class TC_RegExInterpolate < Test::Unit::TestCase
  def test_case_sensitive
    m  = /mike/
    assert_nil(     'Mike' =~ /#{m}/, 'fail Mike')
    assert_equal(0, 'mike' =~ /#{m}/, 'match mike')
  end

  def test_case_insensitive
    m  = /mike/i
    assert_equal(0, 'Mike' =~ /#{m}/, 'match Mike')
    assert_equal(0, 'mIke' =~ /#{m}/, 'match mIke')
    assert_nil(     'pIke' =~ /#{m}/, 'fail pIke')
  end

  def test_simple_char_class
    m = /[Mm]ike/
    assert_equal(0, 'Mike' =~ /#{m}/,  'match Mike')
    assert_nil(     'mIke' =~ /#{m}/,  'fail mIke')
  end

  def test_char_class_with_minus
    m = /[M\-m]ike/
    assert_equal(0, 'Mike' =~ /#{m}/, 'match Mike')
    assert_equal(0, '-ike' =~ /#{m}/, 'match -ike')
    assert_nil(     'mIke' =~ /#{m}/, 'fail mIke')
  end

  def test_cozens_article
    # From http://www.perl.com/pub/a/2003/06/06/regexps.html
    # 
    # my $post_town = qr/[A-Z]{1,2}/;
    # my $area      = qr/\d{1,3}/;
    # my $space     = qr/[ \t]+/;
    # my $region    = qr/\d{1,2}/;
    # my $street    = qr/[A-Z][A-Z]/;
    #
    # And we can also add modifiers to parts of a quoted regular expression:
    #
    # my $uk_postcode = qr/$post_town $area $space $region $street/x;
 
    post_town = /[A-Z]{1,2}/
    area      = /\d{1,3}/
    space     = /[ \t]+/
    region    = /\d{1,2}/
    street    = /[A-Z][A-Z]/

    uk_postcode = /#{post_town} #{area} #{space} #{region} #{street}/x
    
    assert_equal(0, 'BS8 4YA'  =~ /#{uk_postcode}/, "good UK test")
    assert_nil(     'TX 78731' =~ /#{uk_postcode}/, "UK pattern against US code")

    # my $prefix = qr/zip code: /i;
    # my $code   = qr/[A-Z][A-Z][ \t]+\d{5}/;
    #
    # $address =~ /$prefix $code/x;

    prefix = /zip code: /i
    code   = /[A-Z][A-Z][ \t]+\d{5}/

    assert_equal(0, 'Zip Code: TX 78731' =~ /#{prefix} #{code}/x, "good zip test")
  end
end

-- 
mike / stok.co.uk                    |           The "`Stok' disclaimers" apply.
http://www.stok.co.uk/~mike/       | GPG PGP Key      1024D/059913DA 
mike / exegenix.com                  | Fingerprint      0570 71CD 6790 7C28 3D60
http://www.exegenix.com/           |                  75D2 9EC4 C1C0 0599 13DA