On 20.11.2008 14:17, Jes=FAs Gabriel y Gal=E1n wrote:
> On Thu, Nov 20, 2008 at 1:49 PM, John Butler <johnnybutler7 / gmail.com> =
wrote:
>> Hi,
>>
>> I have a regular expression
>> /\b2003|\2004|\2005|\2006|\2007|\2008|\2009\b/
>> and i want to check if various years are present.
>>
>> "2003" =3D~  /\b2003|\2004|\2005|\2006|\2007|\2008|\2009\b/
>> returns 0 as expected
>>
>> "2010" =3D~  /\b2003|\2004|\2005|\2006|\2007|\2008|\2009\b/
>> returns nil as expected
>>
>> But i want only exact matches so when i search for "2003 - 2008" i wan=
t
>> nil returned as there is no exact match for that particular string.  I=

>> thought the \b would give me this but it doesnt.
>>
>> "2003 - 2008" =3D~  /\b2003|\2004|\2005|\2006|\2007|\2008|\2009\b/
>> returns 0 i want nil returned.
>>
>> Anyone help?
>=20
> To do exactly what you are asking for: you can anchor the regexp
> to the beggining or end of the string:
>=20
> irb(main):013:0> re =3D /\A(2003|2004|2005|2006|2007|2008|2009)\Z/
> =3D> /\A(2003|2004|2005|2006|2007|2008|2009)\Z/
> irb(main):014:0> "2003" =3D~ re
> =3D> 0
> irb(main):015:0> "2003 - 2008" =3D~ re
> =3D> nil

I'd rather use /\A200[3-9]\z/.

> In this case you don't need the \b anymore. BTW, you had typos there
> because you had \2 instead of \b.
> Anyway, if you want exact matches of strings you don't need regexps:
>=20
> irb(main):018:0> years =3D (2003..2009).map {|x| x.to_s}
> =3D> ["2003", "2004", "2005", "2006", "2007", "2008", "2009"]
> irb(main):020:0> years.include? "2003"
> =3D> true
> irb(main):021:0> years.include? "2003 - 2008"
> =3D> false

Or

irb(main):001:0> s=3D"2005"
=3D> "2005"
irb(main):002:0> (2003..2009) =3D=3D=3D s[/\A\d{4}\z/].to_i
=3D> true
irb(main):003:0> s=3D"2010"
=3D> "2010"
irb(main):004:0> (2003..2009) =3D=3D=3D s[/\A\d{4}\z/].to_i
=3D> false
irb(main):006:0> (2003..2009).include? s[/\A\d{4}\z/].to_i
=3D> false

Note, this works because 0 (=3D nil.to_i) is not part of the range!

> If you have many numbers and many lookups, a Set should be better,
> performance-wise.

You can even use a bit set:

irb(main):007:0> t =3D (2003..2009).inject(0) {|mask,y| mask | 1 << y}
=3D>=20
1166500786398642596620558532396524895766674785322114323685285020614978521=
5746482388783660380975703702371411000732112621778222728642368642167287462=
5786531963635756068971637276480699799614611885589371789821904502024698121=
3110647305777704740984571138156344394765030929971898877436793132846359287=
4284952185800424567561152820984169201755656484068384334973292443586676017=
3931843810360262352061792429448169450281904579322760817054128336138506834=
4108341835655436648445253912838371081271067917866432685320966720794665123=
9306563177680236700214296738105792019642474717824249726163600825515105290=
1022379808767413846016
irb(main):008:0> t[s.to_i]
=3D> 0
irb(main):009:0> s=3D"2005"
=3D> "2005"
irb(main):010:0> t[s.to_i]
=3D> 1
irb(main):011:0>

There are many ways... :-)

> Now, if we are talking about ranges of years we can do even better:

=2E.. or use the range test (as above) directly.

Kind regards

	robert