字串配方

lua-users home
wiki

以下是 Lua 中用於執行各種常見字串操作的一些建議方案。

子字串匹配

檢查字串 X 是否以字串 Y 開頭或結尾

local function starts_with(str, start)
   return str:sub(1, #start) == start
end

local function ends_with(str, ending)
   return ending == "" or str:sub(-#ending) == ending
end

修剪(移除開頭/結尾空白字元)

請參閱 StringTrim

變更大小寫

將字詞開頭的第一個字母變更為大寫

str = str:gsub("^%l", string.upper)

將字詞開頭的第一個字母變更為大寫

str = str:gsub("%a", string.upper, 1)

將 HTML 標籤變為小寫(但保留屬性名稱不變)

str = str:gsub("<[^%s>]+", string.lower)

將整個字串變更為標題大小寫(例如,將每個字詞的開頭第一個字母大寫)

local function tchelper(first, rest)
   return first:upper()..rest:lower()
end
-- Add extra characters to the pattern if you need to. _ and ' are
--  found in the middle of identifiers and English words.
-- We must also put %w_' into [%w_'] to make it handle normal stuff
-- and extra stuff the same.
-- This also turns hex numbers into, eg. 0Xa7d4
str = str:gsub("(%a)([%w_']*)", tchelper)

範例

> str = "foo"
> str = str:gsub("^%l", string.upper)
> =str
Foo
> str = "_foo"
> str = str:gsub("^%l", string.upper)
> =str
_foo
> str = str:gsub("%a", string.upper, 1)
> =str
_Foo

將所有大寫的字詞轉換為小寫

str = str:gsub("%f[%a]%u+%f[%A]", string.lower)

在此請注意使用「邊界」正規表示式型態 %f。沒有它就難以匹配字詞邊界,包括在要匹配的字串開頭或結尾的邊界。請在字串「AAA bbb CCC dddEEE FFFhhh JJJ」上試試看。如要進一步了解,請閱讀 FrontierPattern

將字串拆分成子字串清單

依據某些分隔字元、字元集或型態拆分原始字串

請參閱 SplitJoin

逐一瀏覽字串中的字詞(改編自 Lua 手冊)

-- words and numbers
for word in str:gmatch("%w+") do ... end

-- identifiers in typical programming languages
for id in str:gmatch("[_%a][_%w]*") do ... end

-- whitespace-separated components (without handling quotes)
for id in str:gmatch("%S+") do ... end

逐一瀏覽緩衝區中的行,忽略空行

(適用於 DOS 和 Unix 行尾約定)

for line in str:gmatch("[^\r\n]+") do ... end

以上任何一種也可以當成函式迭代器來執行

-- call func with each word in a string
str:gsub("%w+", func)

文字換行

在給定的邊界處換行

這是針對其中不含換行符號的字串設計的(亦即在 reflow 文字並將其拆分成多個段落之後)

function wrap(str, limit, indent, indent1)
   indent = indent or ""
   indent1 = indent1 or indent
   limit = limit or 72
   local here = 1-#indent1
   local function check(sp, st, word, fi)
      if fi - here > limit then
         here = st - #indent
         return "\n"..indent..word
      end
   end
   return indent1..str:gsub("(%s+)()(%S+)()", check)
end

將文字 reflow 成段落

此設計建立在 wrap 的基礎上,用於快速且粗略地 reflow:段落定義為開頭為空白字元的行,或彼此之間有空白行的行

function reflow(str, limit, indent, indent1)
   return (str:gsub("%s*\n%s+", "\n")
              :gsub("%s%s+", " ")
              :gsub("[^\n]+",
                    function(line)
                       return wrap(line, limit, indent, indent1)
                    end))
end

重複

檢查字串是否為某個型態的重複

str:gsub(pat, "") == ""

檢查字串是否為某個型態的重複,並且以空白字元分隔

not str:gsub(pat, ""):find"%S"

檢查字串是否為某個型態的重複,且符合某項條件

str:gsub(pat, function(s) return ok(s) and "" or "*" end) == ""

格式化

將變數內插到字串中(字串格式化)

許多程式語言提供將變數格式化為字串的簡潔方法。範例

print( "%-5.5s is %5.2f" % { "pi", math.pi } ) --> pi    is  3.14

請參閱 StringInterpolation 以了解如何在 Lua 中執行此作業。

URL/E-Mail/網頁處理

注意:請另參閱 CgiUtils

解碼經過 URL 編碼的字串

(請注意,只應該在拆分 URL 字串後再解碼;例如,這會讓你能夠正確處理查詢字串或基本部分中的引號「?」字元。)

function url_decode(str)
   str = str:gsub("+", " ")
   str = str:gsub("%%(%x%x)", function(h)
      return string.char(tonumber(h,16))
   end)
   str = str:gsub("\r\n", "\n")
   return str
end

對字串執行 URL 編碼

function url_encode(str)
   if str then
      str = str:gsub("\n", "\r\n")
      str = str:gsub("([^%w %-%_%.%~])", function(c)
         return ("%%%02X"):format(string.byte(c))
      end)
      str = str:gsub(" ", "+")
   end
   return str	
end

匹配電子郵件位址

email="alex@it-rfc.de"
if email:match("[A-Za-z0-9%.%%%+%-]+@[A-Za-z0-9%.%%%+%-]+%.%w%w%w?%w?") then
   print(email .. " is a valid email address")
end

CSV(逗號分隔值)解析

請參閱 CsvUtils

另請參閱


RecentChanges · 喜好
編輯 · 歷史
最後於 2018 年 12 月 7 日下午 03:49 GMT 編輯 (差異)