第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于更高版本,但还是有一些区别。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助支持 Lua 项目


20.1 – 模式匹配函数

字符串库中最强大的函数是 string.find字符串查找)、string.gsub全局替换)和 string.gfind全局查找)。它们都基于模式

与其他几种脚本语言不同,Lua 不使用 POSIX 正则表达式 (regexp) 进行模式匹配。造成这种情况的主要原因是大小:POSIX regexp 的典型实现需要 4,000 多行代码。这比所有 Lua 标准库加起来还要大。相比之下,Lua 中模式匹配的实现不到 500 行。当然,Lua 中的模式匹配无法完成 POSIX 完整实现所能完成的所有操作。尽管如此,Lua 中的模式匹配是一个强大的工具,并且包含一些难以与标准 POSIX 实现相匹配的功能。



string.find 的基本用法是在给定的字符串(称为主题字符串)中搜索模式。该函数返回找到模式的位置,如果找不到,则返回 nil。模式最简单的形式是一个单词,它只匹配其自身的一个副本。例如,模式“hello”将在主题字符串中搜索子字符串“hello”。当 find 找到其模式时,它将返回两个值:匹配开始的索引和匹配结束的索引。

    s = "hello world"
    i, j = string.find(s, "hello")
    print(i, j)                      --> 1    5
    print(string.sub(s, i, j))       --> hello
    print(string.find(s, "world"))   --> 7    11
    i, j = string.find(s, "l")
    print(i, j)                      --> 3    3
    print(string.find(s, "lll"))     --> nil
当匹配成功时,string.find 返回的值的 string.sub 将返回与模式匹配的主题字符串部分。(对于简单的模式,这便是模式本身。)

string.find 函数有一个可选的第三个参数:一个索引,它告诉从主题字符串中的何处开始搜索。当我们想要处理给定模式出现的所有索引时,此参数非常有用。我们反复搜索新模式,每次都从找到前一个模式的位置之后开始。例如,以下代码使用表格记录字符串中所有换行符的位置

    local t = {}                   -- table to store the indices
    local i = 0
    while true do
      i = string.find(s, "\n", i+1)    -- find 'next' newline
      if i == nil then break end
      table.insert(t, i)
    end
稍后我们将看到使用 string.gfind 迭代器编写此类循环的更简单方法。

string.gsub 函数有三个参数:主题字符串、模式和替换字符串。它的基本用法是将替换字符串替换为主题字符串中所有出现的模式

    s = string.gsub("Lua is cute", "cute", "great")
    print(s)         --> Lua is great
    s = string.gsub("all lii", "l", "x")
    print(s)         --> axx xii
    s = string.gsub("Lua is great", "perl", "tcl")
    print(s)         --> Lua is great
可选的第四个参数限制要进行的替换次数
    s = string.gsub("all lii", "l", "x", 1)
    print(s)          --> axl lii
    s = string.gsub("all lii", "l", "x", 2)
    print(s)          --> axx lii

string.gsub 函数还会作为第二个结果返回它进行替换的次数。例如,计算字符串中空格数的一个简单方法是

    _, count = string.gsub(str, " ", " ")
(记住,_ 只是一个虚拟变量名。)