-1

I expect this example to match the two characters <and >:

a = "<1acf457f477b41d4a363e89a1d0a6e57@Open-Xchange>"
a.match /[<>]/
# => #<MatchData "<">

It matches only the first character. Why?

sawa
  • 165,429
  • 45
  • 277
  • 381
ciaoben
  • 3,138
  • 4
  • 27
  • 42

2 Answers2

2

#match only returns the first match as you have seen as MatchData, #scan will return all matches.

>> a="<1acf457f477b41d4a363e89a1d0a6e57@Open-Xchange>"
=> "<1acf457f477b41d4a363e89a1d0a6e57@Open-Xchange>"
>> a.scan /[<>]/
=> ["<", ">"]
Doon
  • 19,719
  • 3
  • 40
  • 44
1

Problem

You are misunderstanding your expression. /[<>]/ means:

Match a single character from the character class, which may be either < or >.

Ruby is correctly giving you exactly what you've asked for in your pattern.

Solution

If you're expecting the entire string between the two characters, you need a different pattern. For example:

"<1acf457f477b41d4a363e89a1d0a6e57@Open-Xchange>".match /<.*?>/
#=> #<MatchData "<1acf457f477b41d4a363e89a1d0a6e57@Open-Xchange>">

Alternatively, if you just want to match all the instances of < or > in your string, then you should use String#scan with a character class or alternation. In this particular case, the results will be identical either way. For example:

"<1acf457f477b41d4a363e89a1d0a6e57@Open-Xchange>".scan /<|>/
#=> ["<", ">"]

"<1acf457f477b41d4a363e89a1d0a6e57@Open-Xchange>".scan /[<>]/
#=> ["<", ">"]
Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199