Programmatically turning a Regexp into an anchored Regexp


#1

Is there any programmatic way to take a Regexp like /foo/ and turn it
into an anchored Regexp (/^foo/)? I’m looking for a programmatic way
to do this because the actual Regexp is dynamic, not known until run
time.

I’m wishing for an option or method similar to the EXTENDED,
IGNORECASE, MULTILINE options, except for anchoring.

I suspect the answer will be “no”, but I wanted to ask anyway before
giving up hope…

Cheers,
Greg


#2

Greg H. schrieb:

Cheers,
Greg

irb(main):001:0> r1 = /foo/
=> /foo/
irb(main):002:0> “the foo in the middle”.gsub(r1, ‘###’)
=> “the ### in the middle”
irb(main):003:0> “foo at the beginning”.gsub(r1, ‘###’)
=> “### at the beginning”
irb(main):004:0> “foo at the beginning”.gsub(/^#{r1}/, ‘###’)
=> “### at the beginning”
irb(main):005:0> “the foo in the middle”.gsub(/^#{r1}/, ‘###’)
=> “the foo in the middle”

O.K.?

Wolfgang Nádasi-Donner


#3

On 2/14/07, Greg H. removed_email_address@domain.invalid wrote:

Is there any programmatic way to take a Regexp like /foo/ and turn it
into an anchored Regexp (/^foo/)? I’m looking for a programmatic way
to do this because the actual Regexp is dynamic, not known until run
time.

I’m wishing for an option or method similar to the EXTENDED,
IGNORECASE, MULTILINE options, except for anchoring.

I suspect the answer will be “no”, but I wanted to ask anyway before
giving up hope…

def anchor( rgxp )
Regexp.new “^#{rgxp.inspect[1…-1]}”
end

I would recommend using the ‘\A’ anchor instead of the ‘^’ anchor.
‘^’ matches at the beginning of a line so that “blah blah\nfoo” would
match. ‘\A’ matches at the beginning of the string so that “blah
blah\nfoo” will not match, but “foo\nblah blah” will match.

def anchor( rgxp )
Regexp.new “\A#{rgxp.inspect[1…-1]}”
end

Blessings,
TwP


#4

On Feb 14, 2007, at 11:50 AM, Greg H. wrote:

Is there any programmatic way to take a Regexp like /foo/ and turn it
into an anchored Regexp (/^foo/)? I’m looking for a programmatic way
to do this because the actual Regexp is dynamic, not known until run
time.

I see you already have your answer, but just to throw other ideas
into the mix:

class String
def matches_at_beginning?(regexp)
(self =~ regexp) == 0
end
end
=> nil

“abc”.matches_at_beginning? /a/
=> true

“abc”.matches_at_beginning? /b/
=> false

And:

require “strscan”
=> true

scanner = StringScanner.new(“abc”)
=> #<StringScanner 0/3 @ “abc”>

scan
scan scanner

scanner.scan(/a/)
=> “a”

sc
scan scanner

scanner.reset
=> #<StringScanner 0/3 @ “abc”>

scanner.scan(/b/)
=> nil

James Edward G. II


#5

On 14 feb, 19:06, Wolfgang Nádasi-Donner removed_email_address@domain.invalid wrote:

irb(main):004:0> “foo at the beginning”.gsub(/^#{r1}/, ‘###’)
=> “### at the beginning”
irb(main):005:0> “the foo in the middle”.gsub(/^#{r1}/, ‘###’)
=> “the foo in the middle”

Thanks, Wolfgang. I had no idea that #{} could be used not only to
interpolate within literal Strings, but within Regexps as well. I now
see that it’s noted on page 66 of The Pickaxe… “In addition, a
regular expression may contain #{…} expression substitutions.”

I tried it out and I see that it also works even if the original
Regexp already has a “^” in it…

Cheers,
Greg