string 在 Lua 中拆分字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1426954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 00:31:55  来源:igfitidea点击:

Split string in Lua?

stringlua

提问by RCIX

I need to do a simple split of a string, but there doesn't seem to be a function for this, and the manual way I tested didn't seem to work. How would I do it?

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

回答by RCIX

Here is my really simple solution. Use the gmatch function to capture strings which contain at least onecharacter of anythingother than the desired separator. The separator is **any* whitespace (%s in Lua) by default:

这是我非常简单的解决方案。使用 gmatch 函数来捕获至少包含一个与所需分隔符不同的任何字符的字符串。默认情况下,分隔符是 **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

.

.

回答by gwell

If you are splitting a string in Lua, you should try the string.gmatch() or string.sub() methods. Use the string.sub() method if you know the index you wish to split the string at, or use the string.gmatch() if you will parse the string to find the location to split the string at.

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

Example using string.gmatch() from Lua 5.1 Reference Manual:

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

回答by Hugo

If you just want to iterate over the tokens, this is pretty neat:

如果您只想遍历令牌,这非常简洁:

line = "one, two and 3!"

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

Output:

输出:

one,

two

and

3!

一,

3!

Short explanation: the "[^%s]+" pattern matches to every non-empty string in between space characters.

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

回答by Norman Ramsey

Just as string.gmatchwill find patternsin a string, this function will find the things betweenpatterns:

就像在字符串中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

By default it returns whatever is separated by whitespace.

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

回答by Faisal Hanif

Here is the function:

这是函数:

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

Call it like:

像这样称呼它:

list=split(string_to_split,pattern_to_match)

e.g.:

例如:

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


For more go here:
http://lua-users.org/wiki/SplitJoin


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

回答by Ivo Beckers

I like this short solution

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

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

回答by Diego Pino

Because there are more than one way to skin a cat, here's my approach:

因为给猫剥皮的方法不止一种,这是我的方法:

Code:

代码

#!/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

Output: 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.

输出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.

Explanation:

说明

The gmatchfunction works as an iterator, it fetches all the strings that match regex. The regextakes all characters until it finds a separator.

gmatch函数用作迭代器,它获取所有匹配的字符串regex。该regex直到它找到一个分离器需要的所有字符。

回答by krsk9999

You can use this method:

您可以使用此方法:

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) 

回答by Hyman Taylor

A lot of these answers only accept single-character separators, or don't deal with edge cases well (e.g. empty separators), so I thought I would provide a more definitive solution.

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

Here are two functions, gsplitand split, adapted from the codein the Scribunto MediaWiki extension, which is used on wikis like Wikipedia. The code is licenced under the GPL v2. I have changed the variable names and added comments to make the code a bit easier to understand, and I have also changed the code to use regular Lua string patterns instead of Scribunto's patterns for Unicode strings. The original code has test cases here.

这里有两个函数,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

Some examples of the splitfunction in use:

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

回答by Hohenheim

a way not seen in others

别人看不到的方式

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