064:文字列をn文字ずつに分割する
正規表現にて - Ruby レシピブック風
正規表現を用い re.findall メソッドや re.finditer メソッドにてリスト、もしくはイテレータを得る、という方法です。
改行 \n も一文字と数えたければ re.S (re.DOTALL) を引数に加えます。
例えば、 4 文字ごとに分割するならば次のようになります。:
>>> import re
>>> re.findall(r'.{1,4}', '123456789', re.DOTALL)
['1234', '5678', '9']
>>> re.findall(r'.{1,4}', u'あいうえおかきく', re.DOTALL)
[u'\u3042\u3044\u3046\u3048', u'\u304a\u304b\u304d\u304f']
>>> print _[0], _[1]
あいうえ おかきく
正規表現を用いるため、日本語などマルチバイト文字を処理する際はユニコード文字列を用いてください。
Ruby レシピブックに習って、一般化してみます。 n 文字ごとに分割する関数は以下のようになります。:
import re
def split_nchars(string, n):
return re.findall(r'.{1,%d}' % n, string, re.DOTALL)
実行するとこのようになります。:
>>> split_nchars(u"あいうえかきくけ", 4) [u'\u3042\u3044\u3046\u3048', u'\u304b\u304d\u304f\u3051'] >>> print _[0], _[1] あいうえ かきくけ >>> split_nchars(u"あいうえか", 4) [u'\u3042\u3044\u3046\u3048', u'\u304b'] >>> print _[0], _[1] あいうえ か >>> split_nchars(u"あいう", 4) [u'\u3042\u3044\u3046'] >>> print _[0] あいう
StringIO? にて
StringIO?.StringIO? クラスは文字列をファイルのように扱うことを可能にします。 このことを利用して read メソッドで n 文字ずつ読み進めます。
文字列を受け取り、結果を n 文字ずつのリストとして返す関数は以下のようになります。:
import StringIO
def split_nchrs(string, n):
sio = StringIO.StringIO(string)
result = []
while True:
s = sio.read(n)
if s:
result.append(s)
else:
break
return result
文字列を受け取り n 文字ずつ返すジェネレータは以下のようになります。:
import StringIO
def split_nchrs_generator(string, n):
sio = StringIO.StringIO(string)
while True:
s = sio.read(n)
if s:
yield s
else:
break
これらに手を加えていけば、ファイルライクオブジェクトから文字列を読み込み、 n 文字ずつ返すジェネレータなどもつくれると思います。