From: "David A. Black" Date: 2008-05-09T09:31:24+09:00 Subject: Re: Doing an AND in regexp char class Hi -- On Fri, 9 May 2008, Todd Benson wrote: > On Thu, May 8, 2008 at 7:00 PM, Joel VanderWerf wrote: >> Todd Benson wrote: >>> >>> On Thu, May 8, 2008 at 6:07 PM, ara.t.howard >>> wrote: >>>> >>>> On May 8, 2008, at 3:40 PM, Todd Benson wrote: >>>>> >>>>> This question arises out of a couple of recent threads and may or may >>>>> not be a Ruby-specific question. >>>>> >>>>> I can check with a character class if one of the characters in the >>>>> class exists or does not exist, but can I use a regexp to check if a >>>>> string absolutely contains all of the characters in the class? >>>>> >>>>> Using a set perspective, I can do it like this in irb... >>>>> >>>>> s1 = "hello there" >>>>> s2 = "ohi" >>>>> (s2.unpack('c*') & s1.unpack('c*')).size == s2.size >>>>> >>>>> => false >>>>> >>>>> I use unpack to avoid creating a bunch of String objects, one for each >>>>> element in the array, which would happen if I used #split. What I'm >>>>> wondering is if there is a way to do this with a simple regexp. >>>>> >>>>> Thanks, >>>>> Todd >>>> >>>> cfp:~ > cat a.rb >>>> class String >>>> def all_chars? chars >>>> tr(chars, '').empty? >>>> end >>>> end >>>> >>>> p 'foobar'.all_chars?('rabof') >>>> p 'foobar'.all_chars?('abc') >>>> p 'foobar'.all_chars?('') >>>> >>>> >>>> >>>> cfp:~ > ruby a.rb >>>> true >>>> false >>>> false >>> >>> Cool :) #tr is one of those useful methods I somehow consistently forget >>> about. >> >> But it can be done with regex, right? It's just more elegant with tr. >> >> class String >> def all_chars? chars >> if chars.empty? >> empty? >> else >> /\A[#{chars}]*\z/ === self >> end >> end >> end >> >> p 'foobar'.all_chars?('rabof') # => true >> p 'foobar'.all_chars?('abc') # => false >> p 'foobar'.all_chars?('') # => false > > I'm drawing a blank here with this one. Why doesn't this work then... > > irb(main):006:0> r = /\A[oh]*\z/ > => /\A[oh]*\z/ > irb(main):007:0> s = "hello, there" > => "hello, there" > irb(main):008:0> r === s > => false "hello, there" contains letters other than o and h, but your regex calls for a string consisting of zero or more o's or h's and nothing else. I think there might be some confusion as between determining that a string contains certain characters, and determining that a string contains *only* certain characters. My understanding was that you wanted the first, which you could do with tr but I think you'd probably want the character cluster to be doing the tr'ing: "oh".tr("hello, there","").empty? # true; all letters in "oh" # are also in "hello, there" "hello, there".tr("ho","").empty? # false They're both strings, of course, so you can do either with Ara's or Joel's methods: "oh".all_chars?("hello, there") # true "hello, there".all_chars?("oh") # false though if it's really the former you want you might want to name it all_present_in? or something. David -- Rails training from David A. Black and Ruby Power and Light: INTRO TO RAILS June 9-12 Berlin ADVANCING WITH RAILS June 16-19 Berlin INTRO TO RAILS June 24-27 London (Skills Matter) See http://www.rubypal.com for details and updates!