tags:

views:

60

answers:

3

Hi,

Can anyone explain why the following test is not passing. The regex is getting a match where I do not want one.

I want to find a match on text that begins with Tel, Fax or Web but for some reason, the url in the test is getting a match:

  def test_url_should_match
    assert_no_match(/^[tel|fax|web]/i, "www.jehall.co.uk")
  end

Thanks for your help.

Paul

+1  A: 

You should use

/^(?:tel|fax|web)/i
KennyTM
Why do you have the Elvis smiley `?:` there?
Aillyn
@Aillyn: So that it doesn't create a capture.
sepp2k
@Aillyn: Are you suggesting the `?:` should not be there?
John Dibling
+3  A: 

Try it with

assert_no_match(/^(tel|fax|web)/i, "www.jehall.co.uk")

That should work. Otherwise you're matching against the characters, i.e. the w in web will match.

Raoul Duke
+4  A: 

[...] in a regular expression specifies a character class, which tells the regular expression engine to match one of these characters contained within brackets. Therefore, [tel|fax|web] means "match t or e or l or | or f or a or x or w or e or b" (the fact that | appears more than once in the class is irrelevant). Since the string starts with a w -- which is in the character class -- the pattern matches.

As other answers have said, you want to use parentheses (...) to group your alternation instead.

Daniel Vandersluis
Actually, the fact that `|` appears multiple times *is* relevant, since it will generate a warning, which, if the OP actually bothered to *read*, would already have told him what is wrong: `warning: character class has duplicated range: /[^[tel|fax|web]]/`
Jörg W Mittag
@Jörg it doesn't give me a warning in irb or on Rubular, but fair point.
Daniel Vandersluis