初版は Lua 5.0 向けに書かれました。後続のバージョンとほとんど関係はありませんが、一部違いがあります。
第 4 版は Lua 5.3 を対象としており、Amazon やその他の書店でご購入いただけます。
書籍を購入することで、Lua プロジェクト支援にもご協力いただけます。


20.1 – パターンマッチング関数

文字列ライブラリで最も強力な関数は、string.find (文字列検索)、string.gsub (全置換)、および string.gfind (全検索) です。これらはすべてパターンに基づいています。

いくつかの他のスクリプト言語とは異なり、Lua ではパターンマッチングに POSIX 正規表現 (regexp) は使用しません。その主な理由はサイズです。POSIX 正規表現の通常のインプリメンテーションでは、4,000 行以上のコードが必要になります。これは、すべての Lua 標準ライブラリの合計よりも大きいです。比較すると、Lua のパターンマッチングのインプリメンテーションは 500 行未満です。もちろん、Lua のパターンマッチングは、完全な POSIX インプリメンテーションと同じことはすべて実行できません。それでも、Lua のパターンマッチングは強力なツールであり、標準の POSIX インプリメンテーションでは実現しにくい機能がいくつか含まれています。



string.find の基本的な使用方法は、対象文字列と呼ばれる特定の文字列内でパターンを検索することです。この関数は、パターンが見つかった位置を返します。見つからなかった場合は nil を返します。パターンの最も簡単な形式は単語で、それ自体のコピーのみと一致します。たとえば、パターン 'hello' は対象文字列内で部分文字列 "hello" を検索します。find がパターンを見つけると、一致の開始インデックスと一致の終了インデックスの 2 つの値を返します。

    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 関数は、オプションの第 3 パラメーターを持ちます。これは、対象文字列内での検索を開始するインデックスを示すものです。このパラメーターは、特定のパターンが表示されるすべてのインデックスを処理する場合に役立ちます。発見した前回のパターンの位置から開始するたび、新しいパターンを繰り返し検索します。例として、次のコードは、文字列内のすべての改行の位置を持つテーブルを作成します。

    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 関数は 3 つのパラメーターがあります: サブジェクト文字列、パターン、および置換文字列。基本的な用途は、置換文字列をサブジェクト文字列内のパターンのすべての出現と置き換えることです

    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
省略可能な 4 番目のパラメーターは、行われる置換の数を制限します
    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 関数は 2 番目の結果として、置換を行った回数も返します。たとえば、文字列内のスペースの数を数える簡単な方法は次のとおりです

    _, count = string.gsub(str, " ", " ")
(覚えているかもしれませんが、 _ はダミーの変数名です。)