Le 03/12/2010 00:22, Philipp Gesang a écrit :
On 2010-12-02<20:59:51>, Paul Isambert wrote:
local sub, gsub = string.sub, string.gsub
function isub (str, pattern, replace, index, num)
   -- Extract the suffix starting at given index
   local s1 = sub(str, index)
   -- Make the replacement on the suffix
   local s2 = gsub(s1, pattern, replace, num)
   -- Replace the suffix in the string with it modified version
   return gsub(str, s1 .. "$", s2)
end

It works, but I find the solution an overkill for what seems to be a
basic operation. So, as I like to ask: have I missed something?
Hi Paul,

“string.sub” takes an optional third argument so that you can do
something like this:

···8<····························································

local sub, gsub = string.sub, string.gsub
function isub (str, pattern, replace, index, num)
   local left  = sub(str, 1, index-1)
   local right = sub(str,index):gsub(pattern, replace, num)
   return left .. right
end

print(isub("abc)abc%def-def",   "b",   "B", 4))
print(isub("abc)abc%def-def", "def", "FED", 1, 1))

···8<····························································

Thank you Philip. That's what I'd figured out in the meanwhile. So there is no "primitive" isub...

If you encounter problems with magic characters in patterns,
there is some assistance waiting in the context helper libs:
http://wiki.contextgarden.net/String_Manipulation#string.escapedpattern.28string.29_.7C_string.partialescapedpattern.28string.29

Are you trying to lure me into ConTeXt? :)
Nice to get inspiration from, though.

PS: What’s the problem with lpeg, anyways?

Nothing, but I don't know how to use it and it seems to me it can't be used lightly; and for the moment I have other things to do. Your code, for instance, which seems to involve a so-called grammar, looks really interesting, except I don't know what lpeg.Cmt, lpeg.Cs, etc., mean, so to me it's unreadable. [Ok, from what I can read, it does the same thing as the above function.]

Best,
Paul

(Yes, probably LPeg, but I don't want to go into that for the
moment.)
···8<····························································

local lpeg = require "lpeg"
local Cmt, Cs, P, V = lpeg.Cmt, lpeg.Cs, lpeg.P, lpeg.V

local function lpeg_gsub (str, pattern, replacement, threshold, limit)
     local idx = 1
     local threshold = threshold or 0
     local sub_cnt = 0

     local peg = P{
         [1] = "initial",

         initial = Cs((V"p" + V"other")^0),

         p = Cmt(P(pattern), function (_,_, matched)
                 if idx>= threshold and
                    ( (limit ~= nil) and (sub_cnt<  limit) or (limit == nil) )
                    then
                     idx = idx + #matched
                     sub_cnt = sub_cnt + 1
                     return true
                 end
                 return false
             end) / replacement,

         other = Cmt(1, function () idx = idx + 1 return true end)
     }

     --peg:print()
     return peg:match(str)
end


local test = "abcdefg abcdefg abcdefg abcdefg"

print(lpeg_gsub(test, "def", "FED", 10))
print(lpeg_gsub(test, "def", "FED", 07, 2))
print(lpeg_gsub(test, "def", "FED", 15))

io.write("\n")

print(lpeg_gsub(test,   "a",   "A", 1, 2))
print(lpeg_gsub(test,   "b",   "B", 4, 1))
print(lpeg_gsub(test,   "c",   "C", 9, 0))
print(lpeg_gsub(test,   "d",   "D", 9))

io.write("\n")

local p1 = P"a" * P(1 - P"g")^1 * P"g"
local p2 = lpeg.S"bdf"
local p3 = lpeg.R"dg"

print(lpeg_gsub(test, p1, "O", 9, 1))
print(lpeg_gsub(test, p2, "O", 1, 3))
print(lpeg_gsub(test, p3, "O", 22))

···8<····························································


Reply via email to