文字列内の特定の部分文字列の出現回数をカウントします


201

Pythonで特定の部分文字列が文字列内に存在する回数をどのようにカウントできますか?

例えば:

>>> 'foo bar foo'.numberOfOccurrences('foo')
2

「部分文字列の数」とはどういう意味ですか?部分文字列の位置は?部分文字列は何回発生しますか?他に何か?
GreenMatt 2012年

2
これは宿題ですか?その場合は、「宿題」というタグを質問に追加してください。また、あなたの質問はあまり明確ではありません。私はあなたが尋ねているように見えるものに答えますが、あなたは本当に何か他のものを見つけたいと思っています。
ジムデラハント

前のコメントに続いて、次の内容をご覧ください。python:別の文字列内の部分文字列を見つける方法、または文字列内の部分文字列の基本的なインデックスの繰り返し(python)。これはおそらくそれらの1つの複製と思われるので、私は閉じることに投票します。
GreenMatt 2012年

@JimDeLaHuntレコードについては、cscircles.cemc.uwaterloo.ca / 8 - remixにこれに関する演習があります - コーディング演習:サブストリングのカウントを参照してください。
Nikos Alexandris

回答:


334

string.count(substring)、 のように:

>>> "abcdabcva".count("ab")
2

更新:

コメントで指摘されているように、これは重複ないオカレンスに対して行う方法です。重複の発生をカウントする必要がある場合は、「Python正規表現がすべての重複する一致を検出しますか?」で回答を確認するか、以下の私のその他の回答を確認してください。


14
これはどうですか:"GCAAAAAG".count("AAA")正解は3ですが、1が返されますか?
漫画家

12
count明らかに、重複しない一致のためです-ほとんどの場合、これはやりたいことです。stackoverflow.com/questions/5616822/...試合を重ねて取引を-しかし、シンプルでは、高価な場合、式は次のとおりです。sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))
jsbueno

一度に複数の単語を数える/検索することは可能ですか?like string.count(substring1、substring2)
Sushant Kulkarni 2017

@SushantKulkarni号ものの、このようなAのことをやってのいずれかの論理的な方法があります:string.count(substring1) + string.count(substring2)。ただし、部分文字列が多数ある場合、これは効率的な方法ではないことに注意してください。各部分文字列をカウントするには、メイン文字列の反復が必要になるためです。
Faheel、

@SushantKulkarniを実行する''.join([substring1, substring2]).count(pattern)と、上記の解決策よりも効率的です。timeitで確認しました。
Enric Calabuig、2018年

23
s = 'arunununghhjj'
sb = 'nun'
results = 0
sub_len = len(sb)
for i in range(len(s)):
    if s[i:i+sub_len] == sb:
        results += 1
print results

4
追加の説明はあなたの答えを改善するでしょう。
ryanyuyu

19

あなたの本当の意味に応じて、次の解決策を提案します。

  1. あなたはスペースで区切られた部分文字列のリストを意味し、すべての部分文字列の中で部分文字列の位置番号が何であるか知りたいです:

    s = 'sub1 sub2 sub3'
    s.split().index('sub2')
    >>> 1
  2. 文字列内のサブ文字列の文字位置を意味します。

    s.find('sub2')
    >>> 5
  3. あなたはsu-bstringの出現の(重複しない)カウントを意味します:

    s.count('sub2')
    >>> 1
    s.count('sub')
    >>> 3

「sub」または「su」を検索してみてください
obohovyk

私はあなたが意味することを推測しs.find("su")、なぜあなたが得るのだろうか0?さて、このサブ文字列の最初のインデックスである"su"ではs。試してみる"ub"と、を取得できます。1たとえば、試してみる"z"-1、部分文字列が見つからない場合と同様に取得できます。
Don質問

つまり、すべてのインデックスではなく、常に最初のインデックスのみが見つかります。@ arun-kumar-khattriが正しい答えを出しました
obohovyk

@ arun-kumar-khattriがあなたが探していた「正しい」答えを出してくれて、私は安心しています。jsbuenoのコメントを追加で確認する必要があるかもしれません。まだ質問していない質問に答えることもあります。
Don Question

3番目のアプローチのように。ところで、私はあなたがそれが重複しないケースのために機能することを言及するべきだと思います。
Zeinab Abbasimazar

12

特定の文字列で重複するサブ文字列を検索する最良の方法は、Python正規表現を使用することです。これは、正規表現ライブラリを使用して、すべての重複する一致を検索します。ここでそれを行う方法は左側が部分文字列で、右側が一致する文字列を提供します

print len(re.findall('(?=aa)','caaaab'))
3

2
おそらく、len(re.findall(f '(?= {sub_string})'、 'caaaab'))を追加して、サブ文字列を動的に挿入することができます:)
Amresh Giri

10

Python 3で文字列内の部分文字列の重複の発生を見つけるために、このアルゴリズムは次のことを行います。

def count_substring(string,sub_string):
    l=len(sub_string)
    count=0
    for i in range(len(string)-len(sub_string)+1):
        if(string[i:i+len(sub_string)] == sub_string ):      
            count+=1
    return count  

私自身がこのアルゴリズムをチェックし、うまくいきました。


1
小さなヒント:「チェックしたので機能する」と言う代わりに、サンプルデータを含むrepl.itなどのオンラインサービスの例を含めることができます。
Valentin

1
コメントバレンティンに感謝します!これが私の最初の答えです。私は次の答えから自分を改善します。
Bharath Kumar R 2017

10

次の2つの方法で頻度をカウントできます。

  1. count()inの使用str

    a.count(b)

  2. または、以下を使用できます。

    len(a.split(b))-1

どこaの文字列であり、bその周波数が計算されるストリングです。


7

メソッドに関する現在のベストアンサーcountは、実際には重複した出現を考慮せず、空のサブ文字列も考慮しません。例えば:

>>> a = 'caatatab'
>>> b = 'ata'
>>> print(a.count(b)) #overlapping
1
>>>print(a.count('')) #empty string
9

重複する部分文字列を考えると、最初の答えは2not 1になります。2番目の答えについては、空の部分文字列がasnwerとして0を返した方が良いでしょう。

次のコードはこれらのことを処理します。

def num_of_patterns(astr,pattern):
    astr, pattern = astr.strip(), pattern.strip()
    if pattern == '': return 0

    ind, count, start_flag = 0,0,0
    while True:
        try:
            if start_flag == 0:
                ind = astr.index(pattern)
                start_flag = 1
            else:
                ind += 1 + astr[ind+1:].index(pattern)
            count += 1
        except:
            break
    return count

今それを実行すると:

>>>num_of_patterns('caatatab', 'ata') #overlapping
2
>>>num_of_patterns('caatatab', '') #empty string
0
>>>num_of_patterns('abcdabcva','ab') #normal
2

6

シナリオ1:文中の単語の出現。例:str1 = "This is an example and is easy"。「is」という単語の出現。できますstr2 = "is"

count = str1.count(str2)

シナリオ2:文中のパターンの出現。

string = "ABCDCDC"
substring = "CDC"

def count_substring(string,sub_string):
    len1 = len(string)
    len2 = len(sub_string)
    j =0
    counter = 0
    while(j < len1):
        if(string[j] == sub_string[0]):
            if(string[j:j+len2] == sub_string):
                counter += 1
        j += 1

    return counter

ありがとう!


このチェックは本当に必要ですか?if(string [j] == sub_string [0]):?後続のif条件で自動的にカバーされませんか?
AnandViswanathan89

AnandViswanathan89、両方とも条件が必要な場合、if(string [j] == sub_string [0])は、メイン文字列内の最初の文字の一致をチェックします。これは、メイン文字列のすべての文字に対して実行する必要があり、if(string [ j:j + len2] == sub_string)は、部分文字列の発生を実行します。最初の発生の場合は、条件が満たされていれば2番目の発生です。
Amith VV

4

質問はあまり明確ではありませんが、表面的には何を求めているのか、お答えします。

文字列Sは長さがL文字で、S [1]が文字列の最初の文字でS [L]が最後の文字である場合、次の部分文字列があります。

  • null文字列 ''。これらの1つがあります。
  • 1からLまでのすべての値Aについて、AからLまでのすべての値Bについて、文字列S [A] .. S [B](両端を含む)。これらの文字列はL + L-1 + L-2 + ... 1あり、合計で0.5 * L *(L + 1)です。
  • 2番目の項目にはS [1] .. S [L]、つまり元の文字列S全体が含まれることに注意してください。

したがって、長さLの文字列内には0.5 * L *(L + 1)+ 1個の部分文字列があります。その式をPythonでレンダリングすると、文字列内に存在する部分文字列の数がわかります。


4

1つの方法はを使用することre.subnです。たとえば'hello'、ケースの任意の組み合わせでの発生数をカウントするには、次のようにします。

import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of "hello"')

私に一言、ありがとう。@santosh、答えを受け入れませんか?
Mawgはモニカを

2

私は受け入れた答えを「単純で明白な方法」として保持しますが、これは重複する出来事をカバーしていません。それらを見つけることは、スライスを複数チェックすることで簡単に行うことができます-次のように:sum( "GCAAAAAGH" [i:]。startswith( "AAA")for i in range(len( "GCAAAAAGH")))

(これにより3が得られます)-正規表現を巧妙に使用することで実行できます。Pythonの正規表現でわかるように、すべての重複する一致を見つけますか?-そして、それは細かいコードゴルフをすることもできます-これは、極端にナイーブにならないようにしようとする文字列のパターンの重複した出現の私の「手作り」の数です(少なくとも、各相互作用で新しい文字列オブジェクトを作成しません):

def find_matches_overlapping(text, pattern):
    lpat = len(pattern) - 1
    matches = []
    text = array("u", text)
    pattern = array("u", pattern)
    indexes = {}
    for i in range(len(text) - lpat):
        if text[i] == pattern[0]:
            indexes[i] = -1
        for index, counter in list(indexes.items()):
            counter += 1
            if text[i] == pattern[counter]:
                if counter == lpat:
                    matches.append(index)
                    del indexes[index]
                else:
                    indexes[index] = counter
            else:
                del indexes[index]
    return matches

def count_matches(text, pattern):
    return len(find_matches_overlapping(text, pattern))

2

重複する発生:

def olpcount(string,pattern,case_sensitive=True):
    if case_sensitive != True:
        string  = string.lower()
        pattern = pattern.lower()
    l = len(pattern)
    ct = 0
    for c in range(0,len(string)):
        if string[c:c+l] == pattern:
            ct += 1
    return ct

test = 'my maaather lies over the oceaaan'
print test
print olpcount(test,'a')
print olpcount(test,'aa')
print olpcount(test,'aaa')

結果:

my maaather lies over the oceaaan
6
4
2

2

重複カウントには、次の使用を使用できます。

def count_substring(string, sub_string):
    count=0
    beg=0
    while(string.find(sub_string,beg)!=-1) :
        count=count+1
        beg=string.find(sub_string,beg)
        beg=beg+1
    return count

重複しない場合は、count()関数を使用できます。

string.count(sub_string)

2

リストを理解できるワンライナーはどうですか?技術的にはその93文字の長さで、PEP-8の純粋さを惜しみません。regex.findallの答えは、高レベルのコードの断片である場合に最も読みやすくなります。低レベルの何かを構築していて、依存関係を望まない場合、これはかなり無駄がなく意味がありません。重複する答えを出しています。もちろん、重複がない場合は、最高スコアの回答のようにcountを使用します。

def count_substring(string, sub_string):
    return len([i for i in range(len(string)) if string[i:i+len(sub_string)] == sub_string])

2

すべてのサブストリング(オーバーラップを含む)をカウントする場合は、このメソッドを使用します。

import re
def count_substring(string, sub_string):
    regex = '(?='+sub_string+')'
    # print(regex)
    return len(re.findall(regex,string))

1

任意の文字列内の部分文字列の数を調べたい場合。以下のコードを使用してください。コードは理解しやすいので、コメントをスキップしました。:)

string=raw_input()
sub_string=raw_input()
start=0
answer=0
length=len(string)
index=string.find(sub_string,start,length)
while index<>-1:
    start=index+1
    answer=answer+1
    index=string.find(sub_string,start,length)
print answer

0

これがすでに見られているかどうかはわかりませんが、これを「使い捨て」という言葉の解決策と考えました。

for i in xrange(len(word)):
if word[:len(term)] == term:
    count += 1
word = word[1:]

print count

どこに単語が単語がありますがで検索すると、用語は、あなたが探している用語であり、


0
string="abc"
mainstr="ncnabckjdjkabcxcxccccxcxcabc"
count=0
for i in range(0,len(mainstr)):
    k=0
    while(k<len(string)):
        if(string[k]==mainstr[i+k]):
            k+=1
        else:
            break   
    if(k==len(string)):
        count+=1;   
print(count)

2
このソリューションが他とどのように異なるかについて詳しく説明できるかもしれませんが、解決できる特別なケースはありますか?
mpaskov 2017年

2
このコードは質問に答えることがありますが、問題を解決する方法や理由に関する追加のコンテキストを提供することで、回答の長期的な価値が向上します。
ドナルドダック

0
import re
d = [m.start() for m in re.finditer(seaching, string)] 
print (d)

これは、文字列で見つかったサブ文字列の回数を検出し、インデックスを表示します。


import re d = [re.finditer(st3、st2)でのmのm.start()]#文字列でサブ文字列が見つかった回数を検索し、インデックスプリントを表示します(d)
Bhaskar Reddi K

0
my_string = """Strings are amongst the most popular data types in Python. 
               We can create the strings by enclosing characters in quotes.
               Python treats single quotes the same as double quotes."""

Count = my_string.lower().strip("\n").split(" ").count("string")
Count = my_string.lower().strip("\n").split(" ").count("strings")
print("The number of occurance of word String is : " , Count)
print("The number of occurance of word Strings is : " , Count)

0

他の2人以上がすでにこのソリューションを提供しているため、反対票を投じるリスク。私もそれらの1つに賛成票を投じました。しかし、私のものはおそらく初心者にとって理解するのが最も簡単です。

def count_substring(string, sub_string):
    slen  = len(string)
    sslen = len(sub_string)
    range_s = slen - sslen + 1
    count = 0
    for i in range(range_s):
        if (string[i:i+sslen] == sub_string):
            count += 1
    return count

0

スペース区切りの単純な文字列の場合、Dictを使用すると非常に高速になります。以下のコードを参照してください

def getStringCount(mnstr:str, sbstr:str='')->int:
    """ Assumes two inputs string giving the string and 
        substring to look for number of occurances 
        Returns the number of occurances of a given string
    """
    x = dict()
    x[sbstr] = 0
    sbstr = sbstr.strip()
    for st in mnstr.split(' '):
        if st not in [sbstr]:
            continue
        try:
            x[st]+=1
        except KeyError:
            x[st] = 1
    return x[sbstr]

s = 'foo bar foo test one two three foo bar'
getStringCount(s,'foo')

0

あなたはstartswithメソッドを使うことができます:

def count_substring(string, sub_string):
    x = 0
    for i in range(len(string)):
        if string[i:].startswith(sub_string):
            x += 1
    return x

0

以下のロジックは、すべての文字列と特殊文字で機能します

def cnt_substr(inp_str, sub_str):
    inp_join_str = ''.join(inp_str.split())
    sub_join_str = ''.join(sub_str.split())

    return inp_join_str.count(sub_join_str)

print(cnt_substr("the sky is   $blue and not greenthe sky is   $blue and not green", "the sky"))

0

Python 3での解決策を次に示します。大文字と小文字は区別されません。

s = 'foo bar foo'.upper()
sb = 'foo'.upper()
results = 0
sub_len = len(sb)
for i in range(len(s)):
    if s[i:i+sub_len] == sb:
        results += 1
print(results)

0
j = 0
    while i < len(string):
        sub_string_out = string[i:len(sub_string)+j]
        if sub_string == sub_string_out:
            count += 1
        i += 1
        j += 1
    return count

2
すべての回答は高く評価されていますが、コードのみの回答では、主題があまり説明されない傾向があります。コンテキストを追加してください。
creyD

0
#counting occurence of a substring in another string (overlapping/non overlapping)
s = input('enter the main string: ')# e.g. 'bobazcbobobegbobobgbobobhaklpbobawanbobobobob'
p=input('enter the substring: ')# e.g. 'bob'

counter=0
c=0

for i in range(len(s)-len(p)+1):
    for j in range(len(p)):
        if s[i+j]==p[j]:
            if c<len(p):
                c=c+1
                if c==len(p):
                    counter+=1
                    c=0
                    break
                continue
        else:
            break
print('number of occurences of the substring in the main string is: ',counter)

0
s = input('enter the main string: ')
p=input('enter the substring: ')
l=[]
for i in range(len(s)):
    l.append(s[i:i+len(p)])
print(l.count(p))

0

これは、文字列内のすべての出現(重複も含む)のリストを作成し、それらをカウントします

def num_occ(str1, str2):
    l1, l2 = len(str1), len(str2)
    return len([str1[i:i + l2] for i in range(l1 - l2 + 1) if str1[i:i + l2] == str2])

例:

str1 ='abcabcd'
str2 = 'bc'

このリストを作成しますが、BOLD値のみを保存します。

[ab、bc、ca、ab、bc、cd]

それは戻ります:

len([bc, bc])

1
なぜこの答え質問あるかのように、少なくともいくつかの説明を追加することを検討してください
β.εηοιτ.βε

0

以下は、重複しない場合と重複する場合の両方で機能するソリューションです。明確にするために:重複する部分文字列とは、最後の文字が最初の文字と同一のものです。

def substr_count(st, sub):
    # If a non-overlapping substring then just
    # use the standard string `count` method
    # to count the substring occurences
    if sub[0] != sub[-1]:
        return st.count(sub)

    # Otherwise, create a copy of the source string,
    # and starting from the index of the first occurence
    # of the substring, adjust the source string to start
    # from subsequent occurences of the substring and keep
    # keep count of these occurences
    _st = st[::]
    start = _st.index(sub)
    cnt = 0

    while start is not None:
        cnt += 1
        try:
            _st = _st[start + len(sub) - 1:]
            start = _st.index(sub)
        except (ValueError, IndexError):
            return cnt

    return cnt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.