文字列の基本¶
================
文字列の結合はplus演算子にて可能¶
>>> "a" + "b"
'ab'
数値はstrを使う必要がある。¶
>>> "a" + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
>>> "a" + str(1)
'a1'
逆に、文字列を数値として使いたかったらintを使う
>>> 1 + "1"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
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 "<stdin>", line 1, in <module>
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')