字符串食谱

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)

文本换行

在给定边距处换行字符串

这适用于没有换行符的字符串(即在重新排版文本并将其分成段落之后)。

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

将文本重新排版成段落

这基于 wrap 来进行快速而肮脏的重新排版:段落定义为以空格开头的行,或者它们之间有空行

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/电子邮件/Web 处理

注意:另请参见 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="[email protected]"
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

另请参见


最近更改 · 偏好设置
编辑 · 历史记录
上次编辑于 2018 年 12 月 7 日下午 3:49 GMT (差异)