home changes contents help options

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 文字ずつ返すジェネレータなどもつくれると思います。