*Luaライブラリ 要注意点 ~正規表現ライブラリライブラリ~ [#y82939dd]

**パターン [#s9c2f1b0]
-LUAのRegexpは他のメジャーなスクリプト言語とは記述方法が異なるため、注意が必要

>パターンは、''string.match''関数などで文字列を検索するために使用されるものです。~
パターンは、特別な意味を持つ特殊文字と、それ以外の通常文字から構成されます。~
通常文字は、それ自身に合致します。~
たとえば、aは、a自身に合致します。~
特殊文字を含まないパターンは、その文字列そのままが対象文字列中から検索されます。~ 
~
パターンで使用する特殊文字は以下のとおりです。

--一般的な正規表現記述では「\」でエスケープするが、LUA独自の表現では、「%」でエスケープする。~
例えば、[%[%]]は各カッコの文字集合となる。~
--文字クラスの小文字と大文字の関係は補集合となる。~
例えば、%wが英数字ならば、%Wは英数字以外である。~
%lや%wなど、文字クラスは「ロケール」に従う。よって厳密には、アルファベットだけが対象ではない。アルファベットのみを対象としたければ[a-zA-Z]など明示すべきである。
--デフォルトは最長マッチ。+は1回以上、*は0回以上の最長マッチ、-は0回以上の最短マッチ。(''-は既存の正規表現でいうところの「*?」と思っておけばよいだろう。'')
--%b<xy>は他言語ではあまり見かけない変わった文字クラスである。~
%b[]などとすると「[」で始まり、「]」で終わる文字列にマッチすることとなる。(これは事実上 一般的な正規表現でいうところの\[.+?\] と同じことであろう)

**キャプチャ(後方参照等) [#p094fc7f]
>パターンは、カッコで囲まれたサブパターンを含むことができ、これをキャプチャと呼びます。~
パターンが合致したときには、キャプチャに相当する部分文字列は保存され、後で使用することができるようになります。~
キャプチャの順序は開きカッコの出現順です。~
~
たとえば、パターン"(a*(.)%w(%s*))"において、最初のキャプチャはa*(.)%w(%s*)に相当する部分文字列であり、~
2番目のキャプチャは.に、3番目のキャプチャは%s*に相当する部分文字列となります。~
~ 
Luaパターンの''特殊なケースとして、空っぽのキャプチャ()は、その場所の文字列の中での位置をキャプチャします''。~
たとえば、パターン"()aa()"を文字列"flaaap"に適用した場合、3と5がキャプチャされます。この空っぽのキャプチャは正規表現では使えません。 

**string.find(str, pattern, init, plain) [#x88b19a6]
>~
|str|文字列型|文字列strの先頭から、パターンpatternに合致する部分を探します。&br;合致する部分が見つかったときには、文字列の先頭が1として、その部分の先頭、最後の位置の2つの数値を戻り値として返します。&br;合致する部分が見つからないときにはnilを返します。|
|pattern|文字列型または正規表現オブジェクト|また、patternがキャプチャを持っている場合には、キャプチャされた文字列は、位置を表す2つの数値に続く戻り値として返されます。|
|init|数値型(FIXNUM)|3つ目の引数initを指定した場合には、パターンpatternを探し始める場所を先頭ではなく、init文字目から始めることができます。&br;initには負の数も指定でき、その場合は末尾から何文字目、という形になります。|
|plain|論理型|4つめの引数plainにtrueを指定した場合には、patternはパターンではなく単なる文字列であると解釈されます。&br;したがって、patternに単純に一致する部分を探すようになります。|
>
#sh(lua]){{
s = "hello world"
  i, j = string.find(s, "hello")
  print(i, j)                         ---> 1, 5
  s.sub(1,5)                          ---> "hello"
}}

**string.find(str, pattern, init, plain) [#x88b19a6]
>~
|str|文字列型|文字列strの先頭から、パターンpatternに合致する部分を探します。&br;合致する部分が見つかったときには、文字列の先頭が1として、その部分の先頭、最後の位置の2つの数値を戻り値として返します。&br;合致する部分が見つからないときにはnilを返します。|
|pattern|文字列型または正規表現オブジェクト|また、patternがキャプチャを持っている場合には、キャプチャされた文字列は、位置を表す2つの数値に続く戻り値として返されます。|
|init|数値型(FIXNUM)|3つ目の引数initを指定した場合には、パターンpatternを探し始める場所を先頭ではなく、init文字目から始めることができます。&br;initには負の数も指定でき、その場合は末尾から何文字目、という形になります。|
|plain|論理型|4つめの引数plainにtrueを指定した場合には、patternはパターンではなく単なる文字列であると解釈されます。&br;したがって、patternに単純に一致する部分を探すようになります。|
#sh(lua){{
table.sort ( tbl,
    function (a, b) 
        return string.lower(a) < string.lower(b) -- 両方小文字にしたものを比較
    end 
)
  a, b = string.find("ABCDE", "BC")        -- a=2, b=3
  a, b = string.find("ABCDE", "%a*")       -- a=1, b=5
  a, b = string.find("ABCDE", /\a*/)       -- a=1, b=5
  a, b = string.find("あいうえお", "いう")   -- a=3, b=6
  a, b, c = string.find("ABCDE", "B(.)D")  -- a=2, b=4, c="C"
}}

**string.sub (s, i [, j]) [#e2739ca6]
>文字 s[i], s[i+1], ..., s[j] の内部コードの数値を返す。~
文字列 s の、位置 i から位置 j までの部分文字列を返す。~
i にも j にも、負の値を使える。~
j が省略されたときは -1 とみなされる~
(つまり文字列の長さと同じ)。特に、string.sub(s,1,j) は s の先頭から j 文字を取り出し、~
string.sub(s, -i) は s の最後の i 文字を取り出す。

**{s:byte(1,-1)}とstring.char(unpack(t)) [#f2c54682]
**string.gsub(str, pattern, repl, n) [#nfd53d31]
>~
|str|文字列型|文字列strに対して、パターンpatternに合致する部分をすべて引数replの指示通りに置き換えた新しい文字列と、patternが見つかった数を返します。文字列strは一切変更されません。|
|pattern|文字列型または正規表現オブジェクト||
|repl|文字列型、テーブル型、関数型のいずれか|replがテーブル型の場合、pattern中の最初のキャプチャをキーとするreplの要素の値が置き換え文字列となります。patternがキャプチャを含まない場合、patternに合致する部分全体がキーとなります。&br;replが関数型の場合、pattern中のすべてのキャプチャを引数としてreplが呼び出され、その戻り値が置き換え文字列となります。patternがキャプチャを含まない場合、patternに合致する部分全体が引数となります。&br;replがテーブル型もしくは関数型の場合、テーブルの要素の値もしくは関数の戻り値が文字列型であれば、それがそのまま置き換え文字列となります。数値型(FIXNUM)の場合は、文字列に変換したものが置き換え文字列になります。&br;テーブルの要素の値もしくは関数の戻り値がfalseあるいはnilの場合には、置き換えは実行されず、元の文字列がそのまま残ります。他の値になった場合には、エラーです。|
|n|数値型(FIXNUM)|4番目の引数nを指定した場合には、置き換えは最初のn個だけ実行されます。&br;省略した場合は、見つかった置き換えはすべて実行されます。&br;replが文字列型の場合、replそのものが置き換え文字列となります。replの中の以下の文字列は特別な意味を持ちます。&br;%0&br; patternに合致する部分全体を表わす。&br;%1~%9&br; patternの中の、指定した順番のキャプチャに合致する文字列を表わす。&br;%%&br; パーセント文字そのものを表わす。|
#sh(lua){{
{s:byte(1,-1)}
}}
で、sに含まれる文字列を全て文字コード化したリストを得ることが出来る。
そして、
#sh(lua){{
string.char(unpack(t))
}}
で元の文字列を構築可能。
#sh(lua){{
s = "abc"
t = {s:byte(1, -1)}
t[1] = t[1] + 1
print(string.char(unpack(t)))  --> "bbc"
}}
  x, y = string.gsub("HELLO world", /o/i, "o")
  -- x = "HELLo world", y = 2

**string.format (formatstring, e1, e2, ...) [#dc2a0bb6]
>(スクリプト言語で、Cファミリーのprintf系譜を持つのは、すでにかなりレガシーな臭いが漂うが…)~
~
最初の引数 (文字列でなければならない) で指定された記述に従い、残りの可変個の引数を書式化して返す。~
書式文字列は標準C関数のprintfファミリーと同じルールに従う。~
''ただし、 *、l、L、n、p、h はサポートされてなくて、追加の q がある点だけが異なる。''~
q オプションは、Luaインタプリタで安全に読み戻せる適切な形式の文字列に書式化する。~
~
その文字列はダブルクォートの間に書かれ、文字列中のダブルクォート、改行、埋め込まれたゼロ、~
バックスラッシュは正しくエスケープされる。~
#sh(lua){{
string.format('%q', 'a string with "quotes" and \n new line')
-- "a string with \"quotes\" and \
-- new line"
  x, y = string.gsub("hello world", "(%w+)", "%1 %1")
  -- x = "hello hello world world", y = 2

  x, y = string.gsub("hello world from Lua", /(\w+)\s*(\w+)/, "%2 %1")
  -- x = "world hello Lua from", y = 2

  t = { name = "lua", version = "5.1" }
  x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
  -- x = "lua-5.1.tar.gz"

  function f(s)
    if s == "hello" then
      return "bye"
    elseif s == "world" then
      return "universe"
    else
      return "unknown"
    end
  end
  x = string.gsub("hello world", "(%w+)", f) -- x = "bye universe"
}}
''c、d、E、e、f, g、G、i、o、u, X、x はすべて数値の引数を期待し、''
''q と s は文字列を期待する。''



トップ   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS