Lua string库整理(v5.1)

string库提供了字符串处理的通用函数。 例如字符串查找、子串、模式匹配等。 当在 Lua 中对字符串做索引时,第一个字符从 1 开始计算(而不是 C 里的 0 )。 索引可以是负数,它指从字符串末尾反向解析。 即,最后一个字符在 -1 位置处,等等。
字符串库中的所有函数都在表string 中。 它还将其设置为字符串元表的__index 域。 因此,你可以以面向对象的形式使用字符串函数。 例如,string.byte(s,i) 可以写成 s:byte(i)。

字符串库假定采用单字节字符编码

string.byte(s[,i[,j]])

返回字符串s[i]. s[i+1],...,s[j]的内部数字编码。i的默认值是1,j的默认值是i

s = 'abc'
print(string.byte(s))
print(string.byte(s,2))
print(string.byte(s,2,3))

Output:
97
98
98  99

string.char(...)

接收零或更多的整数。 返回和参数数量相同长度的字符串。 其中每个字符的内部编码值等于对应的参数值。

print(string.char(98, 99, 100))

Output:
bcd

string.dump(function)

返回包含有以二进制方式表示的(一个 二进制代码块 )指定函数的字符串。 之后可以用 loadstring 调用这个字符串获得 该函数的副本。

function必须是没有upvalues的lua函数。

function dump()
    print("dump test  ")
end

s = string.dump(dump)
print(s)

func = loadstring(s)
func()

Output:
�LuaQ
dump test  

lua 5.3 有改动


string.find(s, pattern [,init [, plain]])

查找第一个字符串 s 中匹配到的 pattern 如果找到一个匹配,find 会返回 s 中关于它起始及终点位置的索引; 否则,返回 nil。 第三个可选数字参数 init 指明从哪里开始搜索; 默认值为 1 ,同时可以是负值。 第四个可选参数 plain 为 true 时, 关闭模式匹配机制。 此时函数仅做直接的 “查找子串”的操作, 而 pattern 中没有字符被看作魔法字符。 注意,如果给定了 plain ,就必须写上 init。

如果在模式中定义了捕获,捕获到的若干值也会在两个索引之后返回。

local s = "abcdefg"
print(string.find(s,"(c)"))
print(string.find(s,"(c)"),1, true)

Output:
3   3   c
3   1   true

string.format(formatstring, ...)

返回不定数量参数的格式化版本, 格式化串为第一个参数(必须是一个字符串)。 格式化字符串遵循 ISO C 函数 sprintf 的规则。 不同点在于选项 *, h, L, l, n, p 不支持, 另外还增加了一个选项 q。 q 选项将一个字符串格式化为两个双引号括起,对内部字符做恰当的转义处理的字符串。 该字符串可以安全的被 Lua 解释器读回来。 例如,调用

string.format('%q', 'a string with "quotes" and \n new line')

会产生字符串:

"a string with \"quotes\" and \new line"

E, e, f, G, and g 都期待一个对应的数字参数。 选项 c, d, i, o, u, X, and x 则期待一个整数。 选项 q 期待一个字符串; 选项 s 期待一个没有内嵌零的字符串。

print(string.format("%d, %s", 1, "a"))

Output:
1, a

string.gmatch(s, pattern)

返回一个迭代器函数。 每次调用这个函数都会继续以 pattern 对 s 做匹配,并返回所有捕获到的值。 如果 pattern 中没有指定捕获,则每次捕获整个 pattern。

对这个函数来说,模板前开始的 '^' 不会当成锚点。因为这样会阻止迭代。

s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
    print(w)
end

Output:
hello
world
from
Lua

string.gsub(s, pattern, repl [, n])

将字符串 s 中,所有的(或是在 n 给出时的前 n 个) pattern 都替换成 repl ,并返回其副本。 repl 可以是字符串、表、或函数。 gsub 还会在第二个返回值返回一共发生了多少次匹配。 gsub 这个名字来源于 Global SUBstitution

如果 repl 是一个字符串,那么把这个字符串作为替换品。 字符 % 是一个转义符: repl 中的所有形式为 %d 的串表示 第 d 个捕获到的子串,d 可以是 1 到 9 。 串 %0 表示整个匹配。 串 %% 表示单个 %。

如果 repl 是张表,每次匹配时都会用第一个捕获物作为键去查这张表。

如果 repl 是个函数,则在每次匹配发生时都会调用这个函数。 所有捕获到的子串依次作为参数传入。

任何情况下,模板中没有设定捕获都看成是捕获整个模板。

如果表的查询结果或函数的返回结果是一个字符串或是个数字, 都将其作为替换用串; 而在返回 falsenil 时不作替换 (即保留匹配前的原始串)。

-- 匹配字符转
-- 先匹配hello, %1 为匹配值,  将hello 替换为hello hello
-- 匹配world时 同理
print(string.gsub("hello world", "(%w+)", "%1 %1"))
print(string.gsub("hello world", "(%w+)", "%0 %0",1))

Output:
hello hello world world 2
hello hello world   1

-- 替换函数
print(string.gsub("4+5 = $return 4+5$", "%$(.-)%$", 
    function (s)
        print(s)
        return loadstring(s)()
    end))

Output:
return 4+5
4+5 = 9 1

--表
local t = {name="lua", version="5.3"}
print(string.gsub("$name-$version.tar.gz", "%$(%w+)", t))

Output:
lua-5.3.tar.gz  2

string.len(s)

接收一个字符串,返回其长度。 空串 "" 的长度为 0 。 内嵌零也统计在内,因此 "a\000bc\000" 的长度为 5 。

print(string.len("hello world \0"))

Output:
13

string.lower(s)

接收一个字符串,将其中的大写字符都转为小写后返回其副本。 其它的字符串不会更改。 对大写字符的定义取决于当前的区域设置。

print(string.lower("HeLLo World"))

Output:
hello world

tring.match(s, pattern [, init])

在字符串 s 中找到第一个能用 pattern匹配到的部分。 如果能找到,match 返回其中的捕获物; 否则返回 nil 。 如果 pattern 中未指定捕获, 返回整个 pattern 捕获到的串。 第三个可选数字参数 init 指明从哪里开始搜索; 它默认为 1 且可以是负数。

print(string.match("hello world", "(%w+)"))
print(string.match("hello world", "(%w+)", -1))

Output:
hello
d

string.rep(s, n)

返回n个字符串s连在一起的字符串

print(string.rep("abc", 2))

Output:
abcabc

lua 5.3 有改动


string.reverse(s)

返回字符串 s 的翻转串。

print(string.reverse("abc"))

Output:
cba

string.sub(s)

返回 s 的子串, 该子串从 i 开始到 j 为止; i 和 j 都可以为负数。 如果不给出 j ,就当它是 -1 (和字符串长度相同)。 特别是, 调用 string.sub(s,1,j) 可以返回 s 的长度为 j 的前缀串, 而 string.sub(s, -i) 返回长度为 i的后缀串。

print(string.sub("Hello World", 5))
print(string.sub("Hello World", -3))

Output:
o World
rld

string.upper(s)

接收一个字符串,将其中的小写字符都转为大写后返回其副本。 其它的字符串不会更改。 对小写字符的定义取决于当前的区域设置。

print(string.upper("Hello World"))

Output:
HELLO WORLD

匹配模式

字符类:

字符类 用于表示一个字符集合。 下列组合可用于字符类:

  • **x: *(这里 x 不能是 魔法字符 ^$()%.[]+-? 中的一员) 表示字符 x 自身。

  • **.: **(一个点)可表示任何字符。

  • **%a: **表示任何字母。

  • **%c: **表示任何控制字符。

  • **%d: **表示任何数字。

  • **%g: **表示任何除空白符外的可打印字符。

  • **%l: **表示所有小写字母。

  • **%p: **表示所有标点符号。

  • **%s: **表示所有空白字符。

  • **%u: **表示所有大写字母。

  • **%w: **表示所有字母及数字。

  • **%x: **表示所有 16 进制数字符号。

  • **%x: **(这里的 x 是任意非字母或数字的字符) 表示字符 x。 这是对魔法字符转义的标准方法。 所有非字母或数字的字符 (包括所有标点,也包括非魔法字符) 都可以用前置一个 '%' 放在模式串中表示自身。

  • **[set]: **表示 set 中所有字符的联合。 可以以 '-' 连接,升序书写范围两端的字符来表示一个范围的字符集。 上面提到的 %x 形式也可以在 set 中使用 表示其中的一个元素。 其它出现在 set 中的字符则代表它们自己。 例如,[%w_] (或 [_%w]) 表示所有的字母数字加下划线), [0-7] 表示 8 进制数字, [0-7%l%-] 表示 8 进制数字加小写字母与 '-' 字符。

    交叉使用类和范围的行为未定义。 因此,像 [%a-z] 或 [a-%%] 这样的模式串没有意义。

  • **[^set]: **表示 set 的补集, 其中 set 如上面的解释。

所有单个字母表示的类别(%a,%c,等), 若将其字母改为大写,均表示对应的补集。 例如,%S 表示所有非空格的字符。

如何定义字母、空格、或是其他字符组取决于当前的区域设置。 特别注意:[a-z] 未必等价于 %l 。

模式条目:

模式条目 可以是

  • 单个字符类匹配该类别中任意单个字符;
  • 单个字符类跟一个 '', 将匹配零或多个该类的字符。 这个条目总是匹配尽可能长的串*;
  • 单个字符类跟一个 '+', 将匹配一或更多个该类的字符。 这个条目总是匹配尽可能长的串
  • 单个字符类跟一个 '-', 将匹配零或更多个该类的字符。 和 '' 不同, 这个条目总是匹配尽可能短的串*;
  • 单个字符类跟一个 '?', 将匹配零或一个该类的字符。 只要有可能,它会匹配一个;
  • %n, 这里的 n 可以从 1 到 9; 这个条目匹配一个等于 n 号捕获物(后面有描述)的子串。
  • %b_xy_, 这里的 xy 是两个明确的字符; 这个条目匹配以 x 开始 y 结束, 且其中 xy 保持 平衡 的字符串。 意思是,如果从左到右读这个字符串,对每次读到一个 x+1 ,读到一个 y-1, 最终结束处的那个y 是第一个记数到 0 的 y。 举个例子,条目 %b() 可以匹配到括号平衡的表达式。
  • %f[set], 指 边境模式; 这个条目会匹配到一个位于 set 内某个字符之前的一个空串, 且这个位置的前一个字符不属于 set 。 集合 set 的含义如前面所述。 匹配出的那个空串之开始和结束点的计算就看成该处有个字符 '\0' 一样。

模式:

模式 指一个模式条目的序列。 在模式最前面加上符号 '^' 将锚定从字符串的开始处做匹配。 在模式最后面加上符号 '$' 将使匹配过程锚定到字符串的结尾。 如果 '^' 和 '$' 出现在其它位置,它们均没有特殊含义,只表示自身。

捕获:

模式可以在内部用小括号括起一个子模式; 这些子模式被称为 捕获物。 当匹配成功时,由 捕获物 匹配到的字符串中的子串被保存起来用于未来的用途。 捕获物以它们左括号的次序来编号。 例如,对于模式 "(a(.)%w(%s))" , 字符串中匹配到 "a(.)%w(%s)" 的部分保存在第一个捕获物中 (因此是编号 1 ); 由 "." 匹配到的字符是 2 号捕获物, 匹配到 "%s*" 的那部分是 3 号。

作为一个特例,空的捕获 () 将捕获到当前字符串的位置(它是一个数字)。 例如,如果将模式 "()aa()" 作用到字符串 "flaaap" 上,将产生两个捕获物: 3 和 5 。

参考链接:http://cloudwu.github.io/lua53doc/manual.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,423评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,339评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,241评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,503评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,824评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,262评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,615评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,337评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,989评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,300评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,829评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,193评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,753评论 3 230
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,970评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,708评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,295评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,207评论 2 258

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,083评论 18 139
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,148评论 0 4
  • Lua Lpeg 用基本匹配函数,组合匹配表达式 所有匹配函数返回userdata类型,是一个匹配模式(以下用pa...
    EternalSunLhx阅读 13,058评论 1 3
  • 体裁:小说 推荐指数:两颗星 有没有因为一件漂亮的衣服,而想要让自己更瘦一点? 有没有因为一束花,而想去美容或者是...
    钟贝拉阅读 325评论 0 1
  • 今天是9月15号,是星期五。 今天我们按周来计算已经开学两周了。今天我们举行了学校初一年级C段班的三跳运动会。我们...
    山榛隰苓阅读 156评论 0 0