home changes contents help options

044:特定の文字を含む部分の長さを調べる

特定の文字列を含む部分の長さを数える

ある文字列が何回現れるか数えるには文字列メソッド count を使います。

>>> s = 'aaaabbaabbaa\n'
>>> s.count('aa')
4

文字数を数えるにはある文字列の長さと出現回数を掛け合わせます。関数にすると次のようになります。

def countlen(pattern, s):
    return len(pattern) * s.count(pattern)
>>> countlen('aa', s)
8
>>> countlen('xx', s)
0

特定の文字を含む部分の長さを調べる

Python には文字型はなく、文字の表現に長さ 1 の文字列を使います。 なので特定の文字を含む部分の長さを調べるには文字列メソッド count がそのままつかえます。

>>> s = 'aaaabbaabbaa\n'
>>> s.count('a')
8

正規表現にマッチする部分の長さを数える

ある正規表現に重複せずマッチする回数を数えるには re.findall メソッドにて得られるマッチした文字列の リストの長さを数えます。

>>> import re
>>> s = 'aaaabbaabbaa\n'
>>> re.findall('a+', s)
['aaaa', 'aa', 'aa']
>>> len(re.findall('a+', s))
3

文字数を数えるには得られたリスト内に含まれる文字数を数えます。

>>> strlist = re.findall('a+', s)
>>> count = 0
>>> for s in strlist:
...   count += len(s)
...
>>> count
8

sum 関数とジェネレータ式を用いて1行で書くとこうなります。

>>> sum(len(s) for s in strlist)
8

よって正規表現に重複せずマッチした文字数を数える関数はこのようになります。

def countlen_re(pattern, s):
    return sum(len(s) for s in re.findall(pattern, s))
>>> countlen_re('a+', s)
8
>>> countlen_re('x+', s)
0

メモリ量節約のため文字列リストを一度に得ないようにするには re.findallre.finditer に置き換えます。 re.finditer はマッチオブジェクトを一つずつ返してきますので、字数を数える際には group() メソッドで マッチした文字列に直しつつ行います。 以下のようになります。

def countlen_re(pattern, s):
    return sum(len(m.group()) for m in re.finditer(pattern, s))