I have a string s= XXaaXX, in which i want to replace the last substring
r, which is determined at run time.
r= XX
s.gsub(/XX\z/,'') solves the problem in a static way.
s.gsub(r,'') solves it too, but who can I specify, that only the last
occurence should be replaced.
s.gsub(/XX\z/,'') solves the problem in a static way.
s.gsub(r,'') solves it too, but who can I specify, that only the last
occurence should be replaced.
Hi, what you really want to use if you want a clean solution is negative
lookaheads built into your regular expression.
How lookaheads work:
Search google for specific lookahead uses in Ruby as I haven't experienced
them yet with this language.
···
On 7/26/06, Tomas Fischer <tomas_fischer99@yahoo.de> wrote:
Hi,
I have a string s= XXaaXX, in which i want to replace the last substring
r, which is determined at run time.
r= XX
s.gsub(/XX\z/,'') solves the problem in a static way.
s.gsub(r,'') solves it too, but who can I specify, that only the last
occurence should be replaced.
Alternatively you can reverse, sub, reverse, but I like Vince's way.
···
On 7/26/06, Vincent Fourmond <vincent.fourmond@9online.fr> wrote:
Hello !
> s.gsub(/XX\z/,'') solves the problem in a static way.
> s.gsub(r,'') solves it too, but who can I specify, that only the last
> occurence should be replaced.
If that's for a single line string, drop the g and just use sub().
James Edward Gray II
···
On Jul 26, 2006, at 6:47 AM, Vincent Fourmond wrote:
Hello !
s.gsub(/XX\z/,'') solves the problem in a static way.
s.gsub(r,'') solves it too, but who can I specify, that only the last
occurence should be replaced.
Well Thomas if your pattern is really at the end of the string you can use
the -- much faster --
anchoring approach Vincent suggested, just escape your regexp and use sub
instead of
gsub as pointed out by Edward in case there is only one line.
s.sub %r{#{Regexp.escape(r)}$}, ""
Robert
···
On 7/26/06, Tomas Fischer <tomas_fischer99@yahoo.de> wrote:
Hi,
thanks for your solutions. But I've forgotten to mention, that r can
contain brackets, so the simple way s.gsub(/#{r}$/,'') doesn't work.
but I am afraid that this is much more expensive than the
reverse.sub.reverse trick and much less readable
Robert
···
On 7/26/06, Guillaume Carbonneau <gusxedge@gmail.com> wrote:
On 7/26/06, Tomas Fischer <tomas_fischer99@yahoo.de> wrote:
>
> Hi,
>
> I have a string s= XXaaXX, in which i want to replace the last substring
> r, which is determined at run time.
>
> r= XX
>
> s.gsub(/XX\z/,'') solves the problem in a static way.
> s.gsub(r,'') solves it too, but who can I specify, that only the last
> occurence should be replaced.
>
> Best regards,
> Tomas
>
> --
> Posted via http://www.ruby-forum.com/\.
>
--
Deux choses sont infinies : l'univers et la bêtise humaine ; en ce qui
concerne l'univers, je n'en ai pas acquis la certitude absolue.
[SNIP]
OP talked about the last occurence, not an occurence at the end, so
anchoring is not an option
reverse sub reverse is a nice idea, I hope you do not mind me spelling it
out
s.reverse.sub(r,"").reverse
and in case U want inline replacement
s.reverse!.sub!(r,"").reverse! # That is rubyish, isn't it :]
Cheers
Robert
···
On 7/26/06, Matthew Harris <shugotenshi@gmail.com> wrote:
Alternatively you can reverse, sub, reverse, but I like Vince's way.
--
Deux choses sont infinies : l'univers et la bêtise humaine ; en ce qui
concerne l'univers, je n'en ai pas acquis la certitude absolue.
but I am afraid that this is much more expensive than the
reverse.sub.reverse trick and much less readable
Robert
Variable length lookahead assertions are a killer, just look at this, I have
replaced the last < in this page with ***
that is a string of length 2369, look at the benchmark please:
n = 50000
Benchmark.bm do |x|
x.report("reverse.sub.reverse") {
n.times do
s1 = string.reverse.sub(r1,"***").reverse
end
}
x.report("lookahead") {
n.times do
s2 = string.sub(r2,"***")
end
}
end
user system total real
reverse.sub.reverse 1.470000 0.010000 1.480000 ( 1.483691)
lookahead 48.100000 0.060000 48.160000 ( 52.608063)
As far as I know fixed with lookahead is about ok, though.
Cheers
Robert
Sorry about yet another post, but I think this is noteworthy...
and yet another
Well that is nice
> actually that would be something like
>
> s.sub( %r{#{Regexp.escape(r)}(?!.*#{Regexp.escape(r)})},"")
>
> but I am afraid that this is much more expensive than the
> reverse.sub.reverse trick and much less readable
>
> Robert
>
Variable length lookahead assertions are a killer, just look at this, I
have
replaced the last < in this page with ***
that is a string of length 2369, look at the benchmark please:
that is stupid
use non greedy
r2 = Regexp.new( "<(?!.*?<)", Regexp::MULTILINE )
n = 50000
Benchmark.bm do |x|
x.report("reverse.sub.reverse") {
n.times do
s1 = string.reverse.sub(r1,"***").reverse
end
}
x.report("lookahead") {
n.times do
s2 = string.sub(r2,"***")
end
}
end
user system total real
reverse.sub.reverse 1.470000 0.010000 1.480000 ( 1.483691)
lookahead 48.100000 0.060000 48.160000 ( 52.608063)
better but not god enough
generous lookahead 14.900000 0.010000 14.910000 ( 15.481074)
As far as I know fixed with lookahead is about ok, though.
···
On 7/26/06, Robert Dober <robert.dober@gmail.com> wrote: