0

I'm trying to figure out how to check if a string matches a regular expression, but I want to know if the entire string matches just once. Here's my code but it seems absurdly long

def single_match(test_me, regex)
  ret_val = false
  test = regex.match(test_me)
  if (test.length==1 && test[0].length == test_me.length)
      ret_val = true
  end
  return ret_val
end

is there an easier way to do this?

P.S. Here's the method I'm really trying to write, since people always seem to ask why I want the gun these days:

def is_int(test_me)
  return single_match(test_me, /[0-9]*/)
end

Edit Thanks everybody. Here's where I'm really using it, but this regex stuff is always interesting to go through. Thanks for the great and educational answers.

Community
  • 1
  • 1
Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421

4 Answers4

7

You don't need to do this, your method can be replaced by using the regular expression of /^[0-9]*$/. The ^ tells it match start of a line and $ tells it match end of the line. So it will match: start of line, 0 to any in range of 0 to 9, and finally end of line.

def is_int(test_me)
  test_me =~ /^[0-9]*$/
end

And you don't need the return statements, Ruby implicitly returns the last statement.

Edit:

It probably would be easier and look better to use the to_i instance method of String class.

def is_int(test_me)
  test_me.to_i.to_s == test_me
end

Edit: (did some tests)

Comparing the performance between the two methods shows that .to_i.to_s == way is 5% faster. So it is up to personal preference to which ever looks better and if you want to handle leading zeroes.

Samuel
  • 37,778
  • 11
  • 85
  • 87
3

To do what you really want should be even simpler

def is_int(test_me)
  test_me.to_i.to_s == test_me
end
DanSingerman
  • 36,066
  • 13
  • 81
  • 92
2

This?

def single_match(str, regex)
  str.match(regex).to_s == str
end
Zach Langley
  • 6,776
  • 1
  • 26
  • 25
1

To answer your original question, for the sake of people finding this page in a search, "scan" will return an array of matches, so if you want to find out how many times some regexp matches, e.g. how many runs of digits there are, you can do:

mystring.scan(/\d+/).size
glenn mcdonald
  • 15,290
  • 3
  • 35
  • 40
  • You would then know how many RUNS of digits there are, but not whether they occupy the whole string (which was the question) or some part of it. Hence setting mystring to "3332b" is the same as "3" with your scanning regex. – Dan Rosenstark Jan 28 '09 at 05:57
  • Ah, ambiguity in the phrase "the entire string matches just once": "there is only one match anywhere in the string" vs "the string is a complete match"... – glenn mcdonald Jan 28 '09 at 21:24
  • Thanks Glenn, I was never informed of your comment, excellent point. – Dan Rosenstark Oct 26 '09 at 18:03