Lua 文字列の位置を取得(string.find)

目次

基本構文

string.find(文字列, 検索対象 [, 開始位置 [, plain]])

string.findは、文字列の中から指定したパターン(または文字列)を検索し、一致した範囲の開始位置と終了位置を返します。

戻り値

  • 見つかった場合 → 開始位置, 終了位置
  • 見つからない場合 → nil

前から検索する

string.find(文字列, 検索する文字列)

string.findは、前から検索し最初の一致の開始・終了位置を返します。

local str1 = "abcabc"

local start_pos, end_pos = string.find(str1, "a")
print(start_pos, end_pos) -- 1 1

start_pos, end_pos = string.find(str1, "b")
print(start_pos, end_pos) -- 2 2

start_pos, end_pos = string.find(str1, "c")
print(start_pos, end_pos) -- 3 3

start_pos, end_pos = string.find(str1, "abc")
print(start_pos, end_pos) -- 1 3

start_pos, end_pos = string.find(str1, "Z")
print(start_pos, end_pos) -- nil nil

Luaのインデックスは1始まりです。

一致しない場合はnilを返します。

 

日本語の場合

日本語の場合は、以下のようになります。(utf-8のとき)

local str2 = "あいうあいう"
local start_pos, end_pos = string.find(str2, "あ")
print(start_pos, end_pos) -- 1 3

start_pos, end_pos = string.find(str2, "い")
print(start_pos, end_pos) -- 4 6

start_pos, end_pos = string.find(str2, "う")
print(start_pos, end_pos) -- 7 9

UTF-8のため日本語の1文字は3バイトになっています。

前から検索する+開始位置を指定

string.find(文字列, 検索する文字列,検索を始める位置)

第3引数は検索を開始する位置です。

指定した位置以降を前から検索します。

 

local str1 = "abcabc"

local start_pos, end_pos = string.find(str1, "a", 1)
print(start_pos, end_pos) -- 1 1

start_pos, end_pos = string.find(str1, "b", 2)
print(start_pos, end_pos) -- 2 2

start_pos, end_pos = string.find(str1, "c", 3)
print(start_pos, end_pos) -- 3 3

start_pos, end_pos = string.find(str1, "a", 4)
print(start_pos, end_pos) -- 4 4

start_pos, end_pos = string.find(str1, "a", 5)
print(start_pos, end_pos) -- nil nil

 

日本語の場合

日本語の場合は、以下のようになります。(utf-8のとき)

local str2 = "あいうあいう"
local start_pos, end_pos = string.find(str2, "あ", 1)
print(start_pos, end_pos) -- 1 3

start_pos, end_pos = string.find(str2, "あ", 4)
print(start_pos, end_pos) -- 10 12

start_pos, end_pos = string.find(str2, "あ", 7)
print(start_pos, end_pos) -- 10 12

start_pos, end_pos = string.find(str2, "あ", 10)
print(start_pos, end_pos) -- 10 12

start_pos, end_pos = string.find(str2, "あ", 11)
print(start_pos, end_pos) -- nil nil

UTF-8のため日本語の1文字は3バイトになっています。

14行目の3つ目の引数の11は「あ」の途中のバイトなので一致しません。

戻り値がnilか確認する時はif文を使用

local str = "abcabc"
local s, e = string.find(str, "Z")

if s then
    print(s, e)
else
    print("not found") -- not found
end

戻り値がnilか確認する時はif文で確認します。

パターン検索

Luaのstring.findは、デフォルトでパターンマッチ(簡易正規表現)を行います。

 

local text = "abc123xyz"

local start_pos, end_pos = string.find(text, "%d+")
print(start_pos, end_pos) -- 4 6

%d+は数字が1回以上続くという意味です。

123に一致します。

 

主なパターン機能

  • %a → アルファベット
  • %s → 空白(スペース・タブ・改行)
  • %d → 数字
  • %w → 英数字(a-zA-Z0-9)
  • %l → 小文字
  • %u → 大文字
  • %p → 記号(punctuation)

+は1回以上の繰り返しです。

  • %d+ → 数字が1回以上続く
  • %a+ → アルファベットが1回以上続く
  • %s+ → 空白が1回以上続く

完全一致(パターンを無効化)

特殊文字をそのまま検索したい場合は、第4引数にtrueを指定します。

 

local text = "a.b.c"

local start_pos, end_pos = string.find(text, ".", 1, true)
print(start_pos, end_pos) -- 2 2

第4引数にtrueをつけるとパターンではなく単純な文字列検索になります(.をそのまま検索)。

関連の記事

Lua 文字列を結合するサンプル

△上に戻る