在Lua中拆分字符串?

RCI*_*CIX 150 string lua

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

小智 81

这是我非常简单的解决方案.使用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
Run Code Online (Sandbox Code Playgroud)

  • 哇,这整个问题的第一个答案实际上有一个返回表的函数.请注意,t和i需要"局部"修饰符,因为它是覆盖全局变量.:) (3认同)
  • 正如其他人所指出的,您可以通过使用table.insert(t,str)而不是t [i] = str来简化这一过程,然后您不需要i = 1或i = i +1 (3认同)
  • 那就对了。在这种情况下,下一个版本将可用:`function split(inputstr,sep)sep = sep或'%s'本地t = {},用于string.gmatch(inputstr,“([[^” .. sep。 。“] *)(” .. sep ..“?)”))如果s ==“”,则执行table.insert(t,field),然后返回t end end end` (3认同)
  • 如果字符串包含空值,则不起作用,例如.''富,, bar'`.你得到`{'foo','bar'}`而不是`{'foo','','bar'}` (2认同)

gwe*_*ell 32

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

使用Lua 5.1参考手册中的 string.gmatch()的示例:

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


Hug*_*ugo 24

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

line = "one, two and 3!"

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

输出:

一,

3!

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

  • 模式“%S”等于您提到的模式,因为“%S”是对“%s”的否定,就像“%D”是对“%d”的否定一样。另外,“%w”等于“ [A-Za-z0-9 _]”(根据您的语言环境,可能支持其他字符)。 (2认同)

Nor*_*sey 14

就像在字符串中string.gmatch找到模式一样,这个函数会找到模式之间的东西:

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
Run Code Online (Sandbox Code Playgroud)

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

  • +1.注意任何其他Lua初学者:这会返回一个迭代器,'patterns patterns'包括字符串的开头和结尾.(作为一个新手,我不得不尝试解决这些问题.) (6认同)

Szc*_*ski 13

如果您使用 Lua 编程,那么您在这里就不走运了。Lua 是一种碰巧臭名昭著的编程语言,因为它的作者从未在标准库中实现“the” split 函数,而是写了 16 整屏的解释和蹩脚的借口,解释为什么他们没有和不会,穿插着许多半工作的例子,这些例子几乎保证对几乎所有人都有效,但在你的极端情况下会中断。这只是 Lua 最先进的技术,每个使用 Lua 编程的人最终都会咬紧牙关并迭代字符。有很多解决方案的存在是有时好,但正好为零解决方案,可靠地更好。


小智 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
Run Code Online (Sandbox Code Playgroud)

称之为:

list=split(string_to_split,pattern_to_match)
Run Code Online (Sandbox Code Playgroud)

例如:

list=split("1:2:3:4","\:")
Run Code Online (Sandbox Code Playgroud)


欲了解更多信息,请访问:http:
//lua-users.org/wiki/SplitJoin


Ivo*_*ers 7

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

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

  • 使用点作为分隔符(或可能是任何其他模式魔术字符)时失败 (2认同)

Die*_*ino 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
Run Code Online (Sandbox Code Playgroud)

输出: 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直到它找到一个分离器需要的所有字符.


Jac*_*lor 6

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

这里有两个函数,gsplitsplit,改编自Scribunto MediaWiki 扩展中代码,该扩展在 Wikipedia 等 wiki 上使用。该代码在GPL v2下获得许可。我更改了变量名称并添加了注释以使代码更容易理解,并且我还更改了代码以使用常规 Lua 字符串模式而不是 Scribunto 的 Unicode 字符串模式。原始代码这里有测试用例。

-- 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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以使用笔灯库。它具有使用输出列表的分隔符分割字符串的功能。

它实现了很多我们在编程时可能需要而Lua中缺少的功能。

这是使用它的示例。

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


小智 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) 
Run Code Online (Sandbox Code Playgroud)


Jer*_*ony 5

只需坐在分隔符上

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


Hoh*_*eim 5

别人看不到的方式

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
Run Code Online (Sandbox Code Playgroud)