文字列の基本 ================== 文字列の結合は+演算子にて可能 :: >>> "a" + "b" 'ab' 数値はstr()を使う必要がある。 :: >>> "a" + 1 Traceback (most recent call last): File "", line 1, in TypeError: cannot concatenate 'str' and 'int' objects >>> "a" + str(1) 'a1' 逆に、文字列を数値として使いたかったらintを使う :: >>> 1 + "1" Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'int' and 'str' >>> 1 + int("1") 2 文字列は「文字の配列」として扱える。 また、また、基本的な配列の使い方についておさらいする。 :: >>> # 0 = 1文字目 >>> "abcdef"[0] 'a' # 3文字目以降を表示 >>> "abcdef"[3:] 'def' # 3文字目までを表示 >>> "abcdef"[:3] 'abc' # -1文字目までを表示 = 最大より1文字少ない >>> "abcdef"[:-1] 'abcde' # 2 から 4より前の文字を表示 >>> "abcdef"[2:4] 'cd' とても簡単な文字列比較の例 :: >>> "abc"[0] == "a" True >>> "ABC"[0] == "a" False 文字列操作 ================== 検索 -------- :: >>> "this is a pen".find("pen") 10 >>> "this is a pen".find("cup") -1 # なので、含まれているかの比較は以下のようにする if string.find("cup") != -1: (-1 = 含まれていない「ではない」時の処理) 置き換え ----------- :: >>> "abc".replace("a", "b") 'bbc' # 文字列も置き換えられる >>> "abc".replace("ab", "xx") 'xxc' 高度な検索や置換の為に: 正規表現 =============================== はじめに ------------ 正規表現は「パターン」を表します。 基本的な使い方を示します。 まずは、柔軟な検索の例として見ます。 ただし、検索だけでは正規表現の「おいしさ」は分かりませんので、 まずは例を実行した後、更に深く進めてください。 パターンの例 -------------- ここはあとでかくこと 検索 ------------ :: >>> # xyという文字列を探します >>> re.search("xy", "abcxyz") <_sre.SRE_Match object at 0x108714cc8> # aの後に「なにか2文字」あってxを探します >>> re.search("a..x", "abcxyz") <_sre.SRE_Match object at 0x108714d30> # aの後に「なにかが0文字以上」あってyzと続く文字列 >>> re.search("a.*yz", "abcxyz") <_sre.SRE_Match object at 0x108714cc8> # aのあとに「bが1文字以上」あるもの >>> re.search("ab+", "aaaabbccc") <_sre.SRE_Match object at 0x108714d30> # なので、以下の例はひっかかりません >>> re.search("ab+", "aaaaccc") # でも、以下はaのあとにbが0文字以上なので引っかかります >>> re.search("ab*", "aaaaccc") <_sre.SRE_Match object at 0x108714d30> なにがひっかかったのか? ------------------------------ groupという関数を利用します :: >>> # aのあとに任意の文字列があってyで終わるものを探す >>> re.search("a.*y", "abcxyz") <_sre.SRE_Match object at 0x108714d30> # なにが引っかかった? >>> re.search("a.*y", "abcxyz").group() 'abcxy' でも、結果がNoneの場合はgroupはないので気をつけてください。 :: >>> # 以下の文字列は引っかからないので、groupという関数がない >>> re.search("a.*d", "abcxyz").group() Traceback (most recent call last): File "", line 1, in AttributeError: 'NoneType' object has no attribute 'group' 文字列の繰り返し ------------------------- >>> # 以下はabcを探します >>> re.search("abc", "abcabcabc").group() 'abc' # 「abc」が*=0個以上続いている文字とマッチします >>> re.search("(abc)*", "abcabcabc").group() 'abcabcabc' # *ではなく、{}で個数の指定も可能です >>> re.search("(abc){1,2}", "abcabcabc").group() 'abcabc' # helのあとにloが1-2個続いているものとマッチします >>> re.search("hel(lo){1,2}", "hellolololo").group() 'hellolo' 文字列単位でのOR ----------------------- >>> >>> re.search("(apple|orange)", "I have a pen.") >>> re.search("(pen|orange)", "I have a pen.").group() 'pen' >>> re.search("(pen|orange)+", "I have a penpenpen.").group() 'penpenpen' 賢い検索 ----------------- 大切なのは「パターン」という認識です。 例えば、incounter: 200という結果があったとします。 このとき、200だけを抜き出したいとします。 以下のように考えます。 "incounter"という文字列がある そのあとに":"があって、" "がある。 そのあと、「数字が適当な数ある」 正規表現を学んだので、以上は"incounter: [0-9]+"や、 "incounter: \d+"と表せることが分かっています。 ここの[0-9]+や\d+の部分が欲しい訳です。 :: >>> re.match("incounter: (\d+)", "incounter: 100").group(1) '100' "\d+"の左右にある「()」がポイントです。これが「パターン」を意味します。 つまり、「数字が1個以上あるパターン」をmatch(するか確認)した訳です。 これを、groupで取り出します。 この中の(1)は「1個目のパターン」という意味です。 「1個目の」と言ったのは意味があります。例えば、 "incounter: 100, outcounter: 200"という文字列があります。 :: >>> re.match("incounter: (\d+), outcounter: (\d+)", "incounter: 100, outcounter: 200").group(1) '100' >>> re.match("incounter: (\d+), outcounter: (\d+)", "incounter: 100, outcounter: 200").group(2) '200' # groupsで全てをタプルの形で得ることもできます >>> re.match("incounter: (\d+), outcounter: (\d+)", "incounter: 100, outcounter: 200").groups() ('100', '200') 置換 ----------------- subで「置き換え」ができます。 何に使うのかは分かりませんが、 "nで始まり:で終わる文字列"を空白に置き換えます。 :: >>> re.sub("n.*:", "", "incount: 100") 'i 100' つぎは、「賢い置換」をします。 "\\n"というnで、「n個目のパターン」という参照が可能です。 :: >>> re.sub("incounter: (\d+)", "IN is \\1!", "incounter: 100") 'IN is 100!' `このサンプル `_