Page 1 of 2

String_exploding improvement

Posted: Mon Apr 25, 2011 1:10 am
by TsT
Hello,

This file is inspired from string exploding :
http://love2d.org/wiki/String_exploding

stringimprove.lua

Code: Select all

local function explode(str, div, plain)
        div = div or "[%s\r\n]+"
        plain = plain or false
        assert(type(str) == "string", "bad argument #1 to 'str' (string expected, got "..type(str)..")")
        assert(type(div) == "string", "bad argument #2 to 'div' (string expected, got "..type(div)..")")
        local o = {}
        while true do
                local pos1,pos2 = str:find(div, nil, plain)
                if not pos1 then
                        o[#o+1] = str
                        break
                end
                o[#o+1],str = str:sub(1,pos1-1),str:sub(pos2+1)
        end
        return o
end

local function split(str, div)
        div = div or " "
        return string.explode(str, div, true)
end

local function join(tbl, sep)
        sep = sep or " "
        assert(type(tbl) == "table", "bad argument #1 to 'tbl' (table expected, got "..type(tbl)..")")
        assert(type(sep) == "string", "bad argument #1 to 'sep' (string expected, got "..type(sep)..")")
        return table.concat(tbl, sep)
end

local function apply(s, t)
        s = s or string
        t = t or table
        s.explode = explode
        s.split   = split
        s.join    = join
        t.join    = join
end

local M = {}
M.explode = explode
M.split   = split
M.join    = join
M.apply   = apply
return M
Sample of use :

Code: Select all

require("stringimprove").apply()

tbl = string.split("foo bar", " ")
print(tbl[1]) --> foo
-- since we added explode to the string table, we can also do this:
str = "foo bar"
tbl2 = str:split(" ")
print(tbl2[2]) --> bar
-- to restore the original string, we can use Lua's table.concat:
original = string.join(tbl, " ")
print(original) --> foo bar

x="a.b.c.d"
x2=string.split(x, ".")
print(string.join(x2, " "))
Open to comment ;-)

EDIT:
minor changes to allow syntax :

Code: Select all

x="a.b.c.d"
x2=x:split(".")
print(x2:join(" "))

Re: String_exploding improvement

Posted: Mon Apr 25, 2011 1:22 am
by thelinx
So, what are the improvements?

Re: String_exploding improvement

Posted: Mon Apr 25, 2011 2:04 am
by TsT
Just easier to use ?

Re: String_exploding improvement

Posted: Mon Apr 25, 2011 6:54 am
by Robin
I would suggest reversing the arguments to string.join. That way you can do:

Code: Select all

(" "):join(tbl)
(as you seemed to be taking the Pythonesk route anyway)

Re: String_exploding improvement

Posted: Mon Apr 25, 2011 7:52 am
by kikito
I'm all about complementing the built-in libs with more methods. There's lots of room for improvements in string and table.

I'd love if the string library in Lua looked more like the ruby string, and the table library was as complete as the ruby array + ruby hash. There's really a lot of room for improvement.

But there's a perfectly valid table.concat. string.join (it seems) just duplicates what table.concat does. I don't see a valid reason for that duplication.

Re: String_exploding improvement

Posted: Mon Apr 25, 2011 6:19 pm
by Robin
kikito wrote:I don't see a valid reason for that duplication.
I do, if the arguments are reversed (see my post above).

Re: String_exploding improvement

Posted: Tue Apr 26, 2011 8:17 am
by BlackBulletIV
kikito wrote:I'd love if the string library in Lua looked more like the ruby string
Well because I've been wanting the same thing for a while, I've created "strong".

Re: String_exploding improvement

Posted: Tue Apr 26, 2011 8:53 am
by TsT
I got problem to made exactly what I have in mind... but nevermind!

BlackBulletIV I really like your strong library !
Don't you want put it on the wiki Libraries page ?

I suggest you a small change to allow spliting with plain text (not regexp)
I prefer default matching as plaintext but the regexp matching seems more usual than plaintext in lua. So I let default as regexp.
Let's allow both !

Code: Select all

function string:split(pat, plaintext)
  plaintext = plaintext and true or false
  local t = {}
  
  while true do
    local pos1, pos2 = self:find(pat, plaintext)

    if not pos1 then
      t[#t + 1] = self
      return t
    end
    
    t[#t + 1] = self:sub(1, pos1 - 1)
    self = self:sub(pos2 + 1)
  end
end
EDIT: typo fix.

Re: String_exploding improvement

Posted: Tue Apr 26, 2011 10:00 am
by BlackBulletIV
Thanks a lot TsT!

I've added the ability to use plain text (see the split function) and noted your help in the README. Note that by using the division operator, it will default to plain text. Use split for patterns.

As for adding it to the libraries page, I'll do that soon.

Note: Lua doesn't use regular expressions, it uses its own patterns I believe.

Re: String_exploding improvement

Posted: Tue Apr 26, 2011 10:52 am
by Robin
BlackBulletIV wrote:Note: Lua doesn't use regular expressions, it uses its own patterns I believe.
Yes. Although based on regexes, Lua patterns are less powerful. In particular, they miss alternation (a|b).