在Lua中拆分字符串?

时间:2009-09-15 12:42:55

标签: string lua

我需要对字符串进行简单的拆分,但似乎没有这个功能,我测试的手动方式似乎不起作用。我该怎么做?

16 个答案:

答案 0 :(得分:76)

这是我非常简单的解决方案。使用gmatch函数捕获包含除所需分隔符以外的ANYTHING的至少一个字符的字符串。默认情况下,分隔符是ANY空格(Lua中为%s):

function mysplit(inputstr, sep)
        if sep == nil then
                sep = "%s"
        end
        local t={}
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                table.insert(t, str)
        end
        return t
end

答案 1 :(得分:30)

如果要在Lua中拆分字符串,则应尝试使用string.gmatch()或string.sub()方法。如果您知道要将字符串拆分为的索引,请使用string.sub()方法;如果要解析字符串以找到将字符串拆分的位置,请使用string.gmatch()。

使用Lua 5.1 Reference Manual中的string.gmatch()的示例:

 t = {}
 s = "from=world, to=Lua"
 for k, v in string.gmatch(s, "(%w+)=(%w+)") do
   t[k] = v
 end

答案 2 :(得分:23)

如果您只想迭代令牌,这非常简洁:

line = "one, two and 3!"

for token in string.gmatch(line, "[^%s]+") do
   print(token)
end

输出:

  

一个,

     

2

     

     

3!

简短说明:“[^%s] +”模式与空格字符之间的每个非空字符串匹配。

答案 3 :(得分:14)

正如string.gmatch会在字符串中找到 patterns 一样,此函数会在模式之间找到之类的东西:

function string:split(pat)
  pat = pat or '%s+'
  local st, g = 1, self:gmatch("()("..pat..")")
  local function getter(segs, seps, sep, cap1, ...)
    st = sep and seps + #sep
    return self:sub(segs, (seps or 0) - 1), cap1 or sep, ...
  end
  return function() if st then return getter(st, g()) end end
end

默认情况下,返回由空格分隔的任何内容。

答案 4 :(得分:11)

这是功能:

function split(pString, pPattern)
   local Table = {}  -- NOTE: use {n = 0} in Lua-5.0
   local fpat = "(.-)" .. pPattern
   local last_end = 1
   local s, e, cap = pString:find(fpat, 1)
   while s do
      if s ~= 1 or cap ~= "" then
     table.insert(Table,cap)
      end
      last_end = e+1
      s, e, cap = pString:find(fpat, last_end)
   end
   if last_end <= #pString then
      cap = pString:sub(last_end)
      table.insert(Table, cap)
   end
   return Table
end

称之为:

list=split(string_to_split,pattern_to_match)

e.g:

list=split("1:2:3:4","\:")


更多信息请点击此处:
http://lua-users.org/wiki/SplitJoin

答案 5 :(得分:7)

我喜欢这个简短的解决方案

function split(s, delimiter)
    result = {};
    for match in (s..delimiter):gmatch("(.-)"..delimiter) do
        table.insert(result, match);
    end
    return result;
end

答案 6 :(得分:6)

因为有一种方法可以给猫皮肤,这是我的方法:

<强>代码

#!/usr/bin/env lua

local content = [=[
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna 
aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
ullamco laboris nisi ut aliquip ex ea commodo consequat.
]=]

local function split(str, sep)
   local result = {}
   local regex = ("([^%s]+)"):format(sep)
   for each in str:gmatch(regex) do
      table.insert(result, each)
   end
   return result
end

local lines = split(content, "\n")
for _,line in ipairs(lines) do
   print(line)
end

<强>输出 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

解释

gmatch函数用作迭代器,它获取与regex匹配的所有字符串。 regex将获取所有字符,直到找到分隔符。

答案 7 :(得分:5)

您可以使用此方法:

function string:split(delimiter)
  local result = { }
  local from  = 1
  local delim_from, delim_to = string.find( self, delimiter, from  )
  while delim_from do
    table.insert( result, string.sub( self, from , delim_from-1 ) )
    from  = delim_to + 1
    delim_from, delim_to = string.find( self, delimiter, from  )
  end
  table.insert( result, string.sub( self, from  ) )
  return result
end

delimiter = string.split(stringtodelimite,pattern) 

答案 8 :(得分:4)

只需坐在分隔符上

local str = 'one,two'
local regxEverythingExceptComma = '([^,]+)'
for x in string.gmatch(str, regxEverythingExceptComma) do
    print(x)
end

答案 9 :(得分:4)

很多这些答案只接受单字符分隔符,或者不能很好地处理边缘情况(例如空分隔符),所以我认为我会提供更明确的解决方案。

以下是两个函数,gsplitsplit,改编自code中的Scribunto MediaWiki extension,用于维基百科等维基。该代码已在GPL v2下获得许可。我已经更改了变量名称并添加了注释以使代码更容易理解,并且我还更改了代码以使用常规Lua字符串模式而不是Scribunto的Unicode字符串模式。原始代码包含测试用例here

-- gsplit: iterate over substrings in a string separated by a pattern
-- 
-- Parameters:
-- text (string)    - the string to iterate over
-- pattern (string) - the separator pattern
-- plain (boolean)  - if true (or truthy), pattern is interpreted as a plain
--                    string, not a Lua pattern
-- 
-- Returns: iterator
--
-- Usage:
-- for substr in gsplit(text, pattern, plain) do
--   doSomething(substr)
-- end
local function gsplit(text, pattern, plain)
  local splitStart, length = 1, #text
  return function ()
    if splitStart then
      local sepStart, sepEnd = string.find(text, pattern, splitStart, plain)
      local ret
      if not sepStart then
        ret = string.sub(text, splitStart)
        splitStart = nil
      elseif sepEnd < sepStart then
        -- Empty separator!
        ret = string.sub(text, splitStart, sepStart)
        if sepStart < length then
          splitStart = sepStart + 1
        else
          splitStart = nil
        end
      else
        ret = sepStart > splitStart and string.sub(text, splitStart, sepStart - 1) or ''
        splitStart = sepEnd + 1
      end
      return ret
    end
  end
end

-- split: split a string into substrings separated by a pattern.
-- 
-- Parameters:
-- text (string)    - the string to iterate over
-- pattern (string) - the separator pattern
-- plain (boolean)  - if true (or truthy), pattern is interpreted as a plain
--                    string, not a Lua pattern
-- 
-- Returns: table (a sequence table containing the substrings)
local function split(text, pattern, plain)
  local ret = {}
  for match in gsplit(text, pattern, plain) do
    table.insert(ret, match)
  end
  return ret
end

正在使用的split函数的一些示例:

local function printSequence(t)
  print(unpack(t))
end

printSequence(split('foo, bar,baz', ',%s*'))       -- foo     bar     baz
printSequence(split('foo, bar,baz', ',%s*', true)) -- foo, bar,baz
printSequence(split('foo', ''))                    -- f       o       o

答案 10 :(得分:4)

如果您在Lua编程,那么您在这里很不幸。 Lua是一种臭名昭著的编程语言,因为它的作者从未在标准库中实现“ the” split函数,而是写了16屏全屏解释和la脚的借口,说明为什么不这样做,不愿意这样做,散布着许多半成品,几乎可以保证几乎每个人都可以使用,但会打破您的极端案例。这只是Lua的最新技术,在Lua中编程的每个人最终都只是咬紧牙关,反复浏览角色。有很多解决方案有时会好一些,但是零解决方案却确实有可靠的更好。

答案 11 :(得分:3)

我使用上面的例子来制作我自己的函数。但对我来说,遗失的部分是自动逃避魔法角色。

这是我的贡献:

function split(text, delim)
    -- returns an array of fields based on text and delimiter (one character only)
    local result = {}
    local magic = "().%+-*?[]^$"

    if delim == nil then
        delim = "%s"
    elseif string.find(delim, magic, 1, true) then
        -- escape magic
        delim = "%"..delim
    end

    local pattern = "[^"..delim.."]+"
    for w in string.gmatch(text, pattern) do
        table.insert(result, w)
    end
    return result
end

答案 12 :(得分:3)

其他人看不见的方式

function str_split(str, sep)
    if sep == nil then
        sep = '%s'
    end 

    local res = {}
    local func = function(w)
        table.insert(res, w)
    end 

    string.gsub(str, '[^'..sep..']+', func)
    return res 
end

答案 13 :(得分:1)

您可以使用penlight library。它具有使用分隔符分割字符串的功能,该分隔符输出列表。

它实现了我们在Lua编程和丢失时可能需要的许多功能。

这里是使用它的示例。

> 
> stringx = require "pl.stringx"
> 
> str = "welcome to the world of lua"
> 
> arr = stringx.split(str, " ")
> 
> arr
{welcome,to,the,world,of,lua}
> 

答案 14 :(得分:1)

对于这个问题来说太晚了,但是如果有人想要一个可以处理您想要的分割数量的版本.....

 select array_concat_agg(x) from (values (ARRAY[1,2]),(ARRAY[3,4,5])) f(x);
 array_concat_agg 
------------------
 {1,2,3,4,5}

答案 15 :(得分:0)

根据用例,这可能会很有用。它将在标志的两边剪切所有文本:

b = "This is a string used for testing"

--Removes unwanted text
c = (b:match("a([^/]+)used"))

print (c)

输出:

string