Thanks for your help. It works very well. It also provides a very good
example for me to learn the "foldl" function.
Inspired by your reply and the implementation of "replace" function defined
in "...\share\julia\base\strings\util.jl", I defined a similar version for
my research, which is copied below for your reference.
function replacematches(f::Function, s::AbstractString, r::Regex)
out = IOBuffer();
pos = foldl((_pos,m) -> begin
write(out, SubString(s, _pos, m.offset-1)) ;
ns::String = f(m);
write(out, ns);
_pos = m.offset + length(m.match);
end, 1, eachmatch(r,s))
write(out, SubString(s, pos));
takebuf_string(out);
end
y = "time format 02:45pm, 14:20, 03:45am. The End."
replacematches(y, r"([01]\d)(:[0-6]\d)(am|pm)"i) do x
lowercase(x.captures[3])=="am"?x.match[1:end-2]:string(parse(Int,
x.captures[1])+12, x.captures[2])
end
Thanks
Yunde
On Thursday, November 12, 2015 at 2:04:58 PM UTC-6, JobJob wrote:
>
> I like that idea, but it's not really available AFAICT.
>
> The function eachmatch(::Regex, ::String) gives you an iterator over the
> match objects.
>
> In any case, I had a little play with this for fun :) - so here's one way
> to do it:
> (n.b. the function arguments don't really need to be typed, I just do it
> to make the code clearer to read):
>
> replacerange(s::AbstractString, replacement::AbstractString,
> range::UnitRange{Int64}) =
> s[1:range.start-1]*replacement*s[range.stop+1:end]
>
> replacematches(s::AbstractString, r::Regex, f::Function) =
> foldl((_s,m) -> begin
> offsetd = length(_s) - length(s) #needed because previous replaces
> may change the length of _s
> repl_range = (offsetd + m.offset):(offsetd + m.offset +
> length(m.match)-1)
> replacerange(_s, f(m), repl_range)
> end, s, eachmatch(r,s))
>
> y = "time format 02:45pm, 14:20, 03:45am"
> replacematches(y, r"([01]\d)(:[0-6]\d)(am|pm)"i,
> x->lowercase(x.captures[3])=="am"?x.match[1:end-2]:string(parse(Int,
> x.captures[1])+12, x.captures[2]))
>
> "time format 14:45, 14:20, 03:45"
>
>
>
>