ฉันต้องแยกสตริงอย่างง่าย ๆ แต่ดูเหมือนจะไม่มีฟังก์ชั่นสำหรับเรื่องนี้และวิธีที่ฉันทดสอบด้วยตนเองดูเหมือนจะไม่ทำงาน ฉันจะทำอย่างไร
ฉันต้องแยกสตริงอย่างง่าย ๆ แต่ดูเหมือนจะไม่มีฟังก์ชั่นสำหรับเรื่องนี้และวิธีที่ฉันทดสอบด้วยตนเองดูเหมือนจะไม่ทำงาน ฉันจะทำอย่างไร
คำตอบ:
นี่คือทางออกที่ง่ายจริงๆของฉัน ใช้ฟังก์ชั่น gmatch เพื่อสตริงการจับภาพที่มีอย่างน้อยหนึ่งตัวละครอะไรอื่นที่ไม่ใช่ตัวคั่นที่ต้องการ ตัวคั่นคือ ** whitespace ใด ๆ (% s ใน Lua) โดยค่าเริ่มต้น:
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
.
'foo,,bar'
. คุณได้รับ{'foo','bar'}
แทน{'foo', '', 'bar'}
function split(inputstr, sep) sep=sep or '%s' local t={} for field,s in string.gmatch(inputstr, "([^"..sep.."]*)("..sep.."?)") do table.insert(t,field) if s=="" then return t end end end
หากคุณแบ่งสตริงใน Lua คุณควรลองใช้วิธี string.gmatch () หรือ string.sub () ใช้เมธอด string.sub () หากคุณรู้จักดัชนีที่คุณต้องการแยกสตริงที่หรือใช้ string.gmatch () หากคุณจะแยกสตริงเพื่อค้นหาตำแหน่งที่จะแยกสตริงที่
ตัวอย่างการใช้ string.gmatch () จากLua 5.1 คู่มืออ้างอิง :
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
หากคุณแค่ต้องการวนซ้ำโทเค็นนี่ก็เรียบร้อยดี:
line = "one, two and 3!"
for token in string.gmatch(line, "[^%s]+") do
print(token)
end
เอาท์พุท:
หนึ่ง,
สอง
และ
3!
คำอธิบายสั้น ๆ : รูปแบบ "[^% s] +" จับคู่กับสตริงที่ไม่ว่างทั้งหมดระหว่างอักขระเว้นวรรค
%S
มีค่าเท่ากับหนึ่งที่คุณกล่าวถึงเป็น%S
เป็นผลทางลบของ%s
เช่นเป็นผลทางลบของ%D
%d
นอกจาก%w
นี้เท่ากับ[A-Za-z0-9_]
(อักขระอื่น ๆ อาจได้รับการสนับสนุนขึ้นอยู่กับสถานที่ของคุณ)
เช่นเดียวกับที่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
โดยปกติแล้วจะส่งคืนสิ่งที่คั่นด้วยช่องว่าง
นี่คือฟังก์ชั่น:
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)
เช่น:
list=split("1:2:3:4","\:")
สำหรับข้อมูลเพิ่มเติมไปที่นี่:
http://lua-users.org/wiki/SplitJoin
ฉันชอบวิธีแก้ปัญหาสั้น ๆ นี้
function split(s, delimiter)
result = {};
for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match);
end
return result;
end
เนื่องจากมีมากกว่าหนึ่งวิธีในการสกินแมวนี่คือวิธีการของฉัน:
รหัส :
#!/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
ฟังก์ชั่นการทำงานเป็น iterator regex
ก็เรียกสตริงทั้งหมดที่จับคู่ การregex
ใช้อักขระทั้งหมดจนกว่าจะพบตัวคั่น
คุณสามารถใช้วิธีนี้:
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)
คำตอบเหล่านี้ส่วนใหญ่ยอมรับเฉพาะตัวคั่นแบบอักขระเดียวหรือไม่จัดการกับตัวพิมพ์เล็ก (เช่นตัวคั่นว่าง) ดังนั้นฉันคิดว่าฉันจะให้คำตอบที่ชัดเจนยิ่งขึ้น
นี่คือสองฟังก์ชันgsplit
และsplit
ปรับเปลี่ยนจากโค้ดในส่วนขยาย Scribunto MediaWikiซึ่งใช้ในวิกิเช่น Wikipedia รหัสที่ได้รับใบอนุญาตภายใต้v2 GPL ฉันได้เปลี่ยนชื่อตัวแปรและเพิ่มความคิดเห็นเพื่อให้โค้ดเข้าใจง่ายขึ้นและฉันได้เปลี่ยนรหัสเพื่อใช้รูปแบบสตริง 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
ตัวอย่างบางส่วนของ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
วิธีที่ไม่เห็นในผู้อื่น
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
เพียงนั่งบนตัวคั่น
local str = 'one,two'
local regxEverythingExceptComma = '([^,]+)'
for x in string.gmatch(str, regxEverythingExceptComma) do
print(x)
end
ฉันใช้ตัวอย่างข้างต้นเพื่อสร้างฟังก์ชั่นของตัวเอง แต่สิ่งที่ขาดหายไปสำหรับฉันคือการหลบหนีตัวละครเวทมนต์
นี่คือผลงานของฉัน:
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
คุณสามารถใช้ไลบรารี่ไลบรารี่ นี่มีฟังก์ชั่นสำหรับการแยกสตริงโดยใช้ตัวคั่นซึ่งแสดงรายการผลลัพธ์
มันใช้งานฟังก์ชั่นมากมายที่เราอาจต้องใช้ในขณะที่เขียนโปรแกรมและขาดหายไปใน Lua
นี่คือตัวอย่างสำหรับการใช้งาน
>
> stringx = require "pl.stringx"
>
> str = "welcome to the world of lua"
>
> arr = stringx.split(str, " ")
>
> arr
{welcome,to,the,world,of,lua}
>
ขึ้นอยู่กับกรณีการใช้งานซึ่งอาจมีประโยชน์ มันตัดข้อความทั้งหมดทั้งสองด้านของธง:
b = "This is a string used for testing"
--Removes unwanted text
c = (b:match("a([^/]+)used"))
print (c)
เอาท์พุท:
string
ช้าไปคำถามนี้ แต่ในกรณีที่ทุกคนต้องการรุ่นที่จัดการกับจำนวนของการแยกที่คุณต้องการได้รับ .....
-- Split a string into a table using a delimiter and a limit
string.split = function(str, pat, limit)
local t = {}
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t, cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
if limit ~= nil and limit <= #t then
break
end
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
ถ้าคุณเขียนโปรแกรมใน Lua คุณโชคไม่ดีที่นี่ Lua เป็นภาษาโปรแกรมหนึ่งที่เพิ่งเกิดขึ้นกับความอับอายขายหน้าเพราะผู้เขียนไม่เคยใช้ "ฟังก์ชั่น" แยก "ในห้องสมุดมาตรฐานและเขียนคำอธิบายและแก้ตัวอ่อนแอ 16 ข้อแทนเพราะเหตุใดพวกเขาจึงไม่ทำ สลับกับตัวอย่างครึ่งการทำงานมากมายที่รับรองว่าจะทำงานได้เกือบทุกคน แต่แตกหักในมุมของคุณ นี่เป็นเพียงศิลปะของลัวะและทุกคนที่ลงโปรแกรมในลัวะก็สามารถฟันและย้ำตัวละครได้ มีโซลูชั่นจำนวนมากที่มีอยู่ซึ่งบางครั้งก็ดีกว่า แต่ก็ไม่มีทางแก้ปัญหาที่ดีกว่าอย่างน่าเชื่อถือ