লুয়া মধ্যে বিভক্ত স্ট্রিং?


160

আমাকে একটি স্ট্রিংয়ের একটি সাধারণ বিভাজন করতে হবে, তবে এটির জন্য এটি কোনও ফাংশন বলে মনে হচ্ছে না, এবং আমি যে ম্যানুয়াল পদ্ধতিতে পরীক্ষা করেছি তাতে কাজ হবে বলে মনে হয় না। আমি এটা কিভাবে করব?


উত্তর:


96

এখানে আমার সত্যিই সহজ সমাধান। স্ট্রিং ক্যাপচারের জন্য গ্যা্যাম্যাচ ফাংশনটি ব্যবহার করুন যাতে কাঙ্ক্ষিত বিভাজক বাদে অন্য কোনও কিছুর অন্তত একটি অক্ষর থাকে । বিভাজক হ'ল ** যে কোনও * সাদা জায়গা (লুয়ায়% 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
ধন্যবাদ। শুধু আমি যা খুঁজছিলাম।
নিকোলাস

3
বাহ, এই পুরো প্রশ্নের প্রথম উত্তরটিতে আসলে একটি ফাংশন রয়েছে যা একটি টেবিল ফেরত দেয়। তবে নোট করুন, সেই টি এবং আমার জন্য "স্থানীয়" সংশোধক প্রয়োজন, এটি হ'ল আপনি বিশ্বব্যাপী ওভাররাইট করছেন। :)
সিবি

3
অন্যরা যেমন উল্লেখ করেছে, আপনি t [i] = str এর পরিবর্তে table.insert (t, str) ব্যবহার করে এটিকে সহজ করতে পারেন এবং তারপরে আপনার i = 1 বা i = i +1 লাগবে না
জেমস নিউটন

2
স্ট্রিংয়ে খালি মান থাকলে, কাজ করে না eg 'foo,,bar'। আপনি পেতে {'foo','bar'}পরিবর্তে{'foo', '', 'bar'}
andras

5
সেটা ঠিক. পরবর্তী সংস্করণ 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
সেক্ষেত্রে

33

আপনি যদি লুয়ায় একটি স্ট্রিং বিভক্ত করছেন, আপনার স্ট্রিং.gmatch () বা স্ট্রিং.সুব () পদ্ধতি ব্যবহার করা উচিত। আপনি যদি সূচকটি স্ট্রিংটিতে বিভক্ত করতে চান তা স্ট্রিং.সুব () পদ্ধতিটি ব্যবহার করুন বা স্ট্রিং.gmatch () ব্যবহার করুন যদি আপনি স্ট্রিংটি বিভক্ত করার জন্য অবস্থানটি অনুসন্ধান করতে স্ট্রিংটিকে বিশ্লেষণ করতে পারেন।

লুয়া 5.1 রেফারেন্স ম্যানুয়াল থেকে স্ট্রিং.gmatch () ব্যবহারের উদাহরণ :

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

আমি যেভাবেই লুয়া ব্যবহারকারীদের পৃষ্ঠা থেকে একটি বাস্তবায়ন "ধার"
পেয়েছি

24

আপনি যদি কেবল টোকেনগুলি দিয়ে পুনরাবৃত্তি করতে চান তবে এটি বেশ ঝরঝরে:

line = "one, two and 3!"

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

আউটপুট:

এক,

দুই

এবং

3!

সংক্ষিপ্ত ব্যাখ্যা: "[^% s] +" প্যাটার্নটি স্থান অক্ষরের মধ্যে থাকা প্রতিটি খালি স্ট্রিংয়ের সাথে মেলে।


2
প্যাটার্ন %S, এক উল্লেখ করেছে সমান হিসাবে %Sঅস্বীকৃতি হয় %s, মত %Dঅস্বীকৃতি হয় %d। অতিরিক্ত হিসাবে, %wসমান [A-Za-z0-9_](আপনার অক্ষরের উপর নির্ভর করে অন্যান্য অক্ষর সমর্থিত হতে পারে)।
লার্স গিরুপ ব্রিংক নীলসন

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

ডিফল্টরূপে এটি হোয়াইটস্পেস দ্বারা পৃথক করা যা কিছু ফিরিয়ে দেয়।


6
+1 টি। অন্য যে কোনও লুয়া শুরুর দিকে নোট করুন: এটি একটি পুনরুক্তি ফেরত দেয় এবং 'নিদর্শনগুলির মধ্যে' স্ট্রিংয়ের শুরু এবং শেষ অন্তর্ভুক্ত। (একটি নবাগত হিসাবে আমি এই জিনিসগুলি বের করার চেষ্টা করেছিলাম।)
দারিয়াস বেকন

12

ফাংশনটি এখানে:

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


7

আমি এই সংক্ষিপ্ত সমাধানটি পছন্দ করি

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

এটি আমার প্রিয়, যেহেতু এটি খুব সংক্ষিপ্ত এবং সহজ। আমি কি বুঝতে পারি না কি হয়, কেউ আমাকে বোঝাতে পারে?
ষড়ভুজ

2
বিন্দুটিকে ডিলিমিটার হিসাবে ব্যবহার করার সময় এটি ব্যর্থ হয় (বা সম্ভাব্যত কোনও অন্য ধরণের যাদুর চরিত্র)
টার্বোহেজেড

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কোনো ইটারেটরে যেমন ফাংশন কাজ, এটা যে ম্যাচ সব স্ট্রিং নিয়ে আসে regexregexযতক্ষণ না এটি একটি বিভাজক খুঁজে বের করে সমস্ত অক্ষর লাগে।


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) 

5

এই উত্তরগুলির মধ্যে অনেকগুলি কেবল একক-চরিত্রের বিভাজককে গ্রহণ করে, বা প্রান্তের কেসগুলি ভালভাবে মোকাবেলা করবেন না (যেমন খালি বিভাজক), তাই আমি ভেবেছিলাম যে আমি আরও নির্দিষ্ট সমাধান দেব।

এখানে দুটি ফাংশন, হয় gsplitএবং split, থেকে অভিযোজিত কোড মধ্যে Scribunto মিডিয়াউইকি এক্সটেনশন , যা উইকিপিডিয়া মত উইকিস উপর ব্যবহার করা হয়। কোডটি জিপিএল ভি 2 এর অধীনে লাইসেন্সযুক্ত । কোডটি বুঝতে কিছুটা সহজ করার জন্য আমি পরিবর্তনশীল নাম পরিবর্তন করেছি এবং মন্তব্যগুলি যুক্ত করেছি এবং আমি ইউনিকোড স্ট্রিংয়ের জন্য স্ক্রিবুন্টোর প্যাটার্নগুলির পরিবর্তে নিয়মিত লুয়া স্ট্রিং প্যাটার্নগুলি ব্যবহার করার জন্য কোডও পরিবর্তন করেছি। মূল কোডটিতে এখানে পরীক্ষার কেস রয়েছে

-- 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

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


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

এটি আমার বড় সমস্যাও ছিল। এটি যাদু চরিত্রগুলি সহ দুর্দান্ত কাজ করে
অ্যান্ড্রু হোয়াইট

1

আপনি পেনলাইট লাইব্রেরি ব্যবহার করতে পারেন । এটি ডিলিমিটার যা আউটপুট তালিকার সাহায্যে বিভাজন স্ট্রিংয়ের জন্য একটি ফাংশন রয়েছে।

এটি লুয়াতে প্রোগ্রামিং এবং অনুপস্থিত থাকার সময় আমাদের প্রয়োজন হতে পারে এমন অনেকগুলি কার্যকারিতা বাস্তবায়ন করেছে।

এটি ব্যবহারের জন্য নমুনা এখানে।

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

0

ব্যবহারের ক্ষেত্রে নির্ভর করে এটি কার্যকর হতে পারে। এটি পতাকাগুলির উভয় পাশেই সমস্ত পাঠ্য কেটে দেয়:

b = "This is a string used for testing"

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

print (c)

আউটপুট:

string

0

এই প্রশ্নের পক্ষে খুব দেরী, তবে যদি কেউ এমন একটি সংস্করণ চায় যা আপনি যে পরিমাণ বিভাজন করতে চান তা পরিচালনা করে .....

-- 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

0

আপনি যদি লুয়ায় প্রোগ্রাম করেন তবে আপনার ভাগ্য এখানে নেই। লুয়া হ'ল একটি প্রোগ্রামিং ল্যাঙ্গুয়েজ যা কেবল কুখ্যাত কুখ্যাত হবে কারণ এর লেখকরা কখনও স্ট্যান্ডার্ড লাইব্রেরিতে "" "বিভক্ত ফাংশন প্রয়োগ করেননি, এবং পরিবর্তে 16 টি স্ক্রিনফুল লিখেছেন এবং কেন করেন নি, এই কারণেই ব্যাখ্যা এবং খোঁড়া অজুহাত প্রকাশ করেছেন wrote প্রায় প্রতিটি কাজের জন্য কার্যত গ্যারান্টিযুক্ত তবে আপনার কোণার ক্ষেত্রে বিরতি দেয় এমন অসংখ্য অর্ধ-কাজের উদাহরণ সহ ছেদ করা । এটি কেবল শিল্পের লুয়া রাজ্য এবং লুয়ায় যারা প্রোগ্রাম করেন কেবল তারা দাঁত ক্লিঙ্কিং করে এবং অক্ষরগুলি পুনরুক্ত করে। অস্তিত্বের অনেকগুলি সমাধান রয়েছে যা কখনও কখনও উন্নত হয় তবে ঠিক শূন্য সমাধান যা নির্ভরযোগ্যভাবে আরও ভাল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.