计算字符串中子字符串出现的次数
Posted
技术标签:
【中文标题】计算字符串中子字符串出现的次数【英文标题】:Count number of occurrences of a substring in a string 【发布时间】:2012-02-12 13:38:43 【问题描述】:如何计算给定子字符串在 Python 中的字符串中出现的次数?
例如:
>>> 'foo bar foo'.numberOfOccurrences('foo')
2
【问题讨论】:
“子串的数量”是什么意思?子串的位置?子串出现多少次?还有什么? 这是家庭作业吗?如果是这样,请在您的问题中添加标签“作业”。另外,你的问题不是很清楚。我会回答你似乎在问的问题,但我怀疑你真的想找出其他东西。 在之前的评论之后,您可能希望看到:python: How to find a substring in another string 或 Basic indexing recurrences of a substring within a string (python)。由于这似乎与其中一个重复,我投票结束。 @JimDeLaHunt 作为记录,cscircles.cemc.uwaterloo.ca/8-remix 中有一个关于此的练习——请参阅编码练习:子字符串计数。 Basic indexing recurrences of a substring within a string (python)的可能重复 【参考方案1】:def count_substring(string, sub_string):
k=len(string)
m=len(sub_string)
i=0
l=0
count=0
while l<k:
if string[l:l+m]==sub_string:
count=count+1
l=l+1
return count
if __name__ == '__main__':
string = input().strip()
sub_string = input().strip()
count = count_substring(string, sub_string)
print(count)
【讨论】:
嗨。请解释您的解决方案。【参考方案2】:如果您正在寻找适用于所有情况的电源解决方案,此功能应该可以工作:
def count_substring(string, sub_string):
ans = 0
for i in range(len(string)-(len(sub_string)-1)):
if sub_string == string[i:len(sub_string)+i]:
ans += 1
return ans
【讨论】:
【参考方案3】:def count_substring(string, sub_string):
counterList=[ 1 for i in range(len(string)-len(sub_string)+1) if string[i:i+len(sub_string)] == sub_string]
count=sum(counterList)
return count
if __name__ == '__main__':
string = input().strip()
sub_string = input().strip()
count = count_substring(string, sub_string)
print(count)
【讨论】:
【参考方案4】:如果你想计算整个字符串,这可以工作。
stri_count="If you're looking to count the whole string this can works"
print(len(stri_count))
【讨论】:
嗨,Jean,欢迎来到 Stack Overflow!虽然这是有趣的信息,但遗憾的是它并没有回答最初提出的问题 - 请考虑添加有趣的信息,这些信息不是对未来作为 cmets 提出的问题的直接答案。除此之外,x.count('')
实际上返回字符串长度 + 1。len(x)
将是检索字符串长度的更典型方法。【参考方案5】:
def count_substring(string, sub_string):
inc = 0
for i in range(0, len(string)):
slice_object = slice(i,len(sub_string)+i)
count = len(string[slice_object])
if(count == len(sub_string)):
if(sub_string == string[slice_object]):
inc = inc + 1
return inc
if __name__ == '__main__':
string = input().strip()
sub_string = input().strip()
count = count_substring(string, sub_string)
print(count)
【讨论】:
附上这段代码的解释会很有帮助。【参考方案6】:这是一个适用于非重叠和重叠事件的解决方案。澄清一下:重叠子字符串的最后一个字符与其第一个字符相同。
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
【讨论】:
重叠子字符串是最后一个字符与其第一个字符相同的子字符串 并且其长度为> 1
- 否则为'a'
,对于例如,将是一个重叠的子字符串。为聪明的想法 +1。
经过一番思考后,我得出结论,这个定义(关于第一个和最后一个字符)是错误的 - 考虑子字符串laplap
。【参考方案7】:
场景1:一个词在一个句子中的出现。
例如:str1 = "This is an example and is easy"
。 “是”这个词的出现。让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,Both if 条件都需要, if(string[j] == sub_string[0]) 检查主字符串中的初始字符匹配,必须对整个字符执行主字符串和 if(string[j:j+len2] == sub_string) 执行子字符串的出现。如果是第一次出现,那么第二次如果条件就足够了。【参考方案8】:这将列出字符串中所有出现(也重叠)的列表并计算它们
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])
【讨论】:
请考虑添加至少一些解释,好像为什么这回答了这个问题【参考方案9】:string.count(substring)
,比如:
>>> "abcdabcva".count("ab")
2
更新:
正如 cmets 中所指出的,这是针对 非重叠 事件的方法。如果您需要计算重叠出现的次数,您最好查看以下答案:“Python regex find all overlapping matches?”,或者只需查看下面我的其他答案。
【讨论】:
这个呢:"GCAAAAAG".count("AAA")
给出 1,而正确答案是 3?
count
显然适用于非重叠匹配——这通常是人们想要做的。 ***.com/questions/5616822/… 处理重叠匹配 - 但一个简单但昂贵的表达式是:sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))
是否可以一次计算/搜索多个单词?像 string.count(substring1, substring2)
@SushantKulkarni 不。虽然有一种合乎逻辑的方式来做这样的事情:string.count(substring1) + string.count(substring2)
。但是请记住,如果有很多子字符串,这不是一种有效的方法,因为计算每个子字符串需要对主字符串进行迭代。
@SushantKulkarni 做''.join([substring1, substring2]).count(pattern)
比上面建议的解决方案更有效。我使用 timeit 进行了检查。【参考方案10】:
如果你想统计所有的子串(包括重叠的)那么就用这个方法。
import re
def count_substring(string, sub_string):
regex = '(?='+sub_string+')'
# print(regex)
return len(re.findall(regex,string))
【讨论】:
【参考方案11】: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))
【讨论】:
【参考方案12】:#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)
【讨论】:
【参考方案13】: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
【讨论】:
虽然所有答案都值得赞赏,但仅代码的答案往往不能很好地解释该主题。请添加一些上下文。【参考方案14】:这是 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)
【讨论】:
【参考方案15】:根据您的实际意思,我提出以下解决方案:
您的意思是一个空格分隔的子字符串列表,并且想知道所有子字符串中的子字符串位置编号是多少:
s = 'sub1 sub2 sub3'
s.split().index('sub2')
>>> 1
你的意思是字符串中子字符串的字符位置:
s.find('sub2')
>>> 5
您的意思是子字符串出现的(不重叠的)计数:
s.count('sub2')
>>> 1
s.count('sub')
>>> 3
【讨论】:
尝试查找“sub”或“su” 我猜你的意思是s.find("su")
,想知道为什么你会得到0
?这是s
中子字符串"su"
的第一个索引。试试"ub"
,你会得到1
,试试例如"z"
,你会得到-1
,因为没有找到子字符串。
我的意思是你总是只找到第一个索引,而不是所有索引,@arun-kumar-khattri 给出了正确答案
@arun-kumar-khattri 给出了您正在寻找的“正确”答案,这让我松了一口气。也许你应该多看看 jsbueno 的 cmets,有时他们会回答你还没问过的问题。
喜欢第三种方法。顺便说一句,我认为您应该提到它适用于不重叠的情况。【参考方案16】:
以下逻辑适用于所有字符串和特殊字符
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"))
【讨论】:
【参考方案17】:您可以使用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
【讨论】:
【参考方案18】:对于一个带空格分隔的简单字符串,使用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')
【讨论】:
【参考方案19】:您可以使用两种方式计算频率:
在str
中使用count()
:
a.count(b)
或者,您可以使用:
len(a.split(b))-1
其中a
是字符串,b
是要计算其频率的子字符串。
【讨论】:
【参考方案20】:冒着投反对票的风险,因为 2+ 其他人已经提供了此解决方案。我什至对其中一个投了赞成票。但我的可能是新手最容易理解的。
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
【讨论】:
【参考方案21】:带有列表理解的单行代码怎么样?从技术上讲,它有 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])
【讨论】:
【参考方案22】: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)
【讨论】:
【参考方案23】:一种方法是使用re.subn
。例如,要计算数量
'hello'
在你可以做的任何情况下出现:
import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of "hello"')
【讨论】:
告诉我,谢谢。 @santosh,为什么不接受答案?【参考方案24】:在给定字符串中查找重叠子字符串的最佳方法是使用 python 正则表达式,它将使用正则表达式库查找所有重叠匹配。左边是子字符串,右边是要匹配的字符串
print len(re.findall('(?=aa)','caaaab'))
3
【讨论】:
也许你可以添加 len(re.findall(f'(?=sub_string)','caaaab')) 动态插入子字符串:)【参考方案25】:import re
d = [m.start() for m in re.finditer(seaching, string)]
print (d)
这会查找在字符串中找到子字符串的次数并显示索引。
【讨论】:
import re d = [m.start() for m in re.finditer(st3, st2)] #查找子字符串在字符串中找到的次数并显示索引 print(d) 【参考方案26】:对于重叠计数,我们可以使用:
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)
【讨论】:
【参考方案27】:如果您想找出任何字符串中的子字符串的计数;请使用下面的代码。 代码很容易理解,这就是我跳过 cmets 的原因。 :)
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
【讨论】:
【参考方案28】:要在 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
我自己检查了这个算法,它确实有效。
【讨论】:
小提示:您可以在repl.it 之类的在线服务中包含一些示例数据,而不是说“它有效,因为我检查了它”。 感谢您的评论瓦伦丁!这是我在这里的第一个答案。我会从下一个答案中改进自己。【参考方案29】:涉及方法count
的当前最佳答案并没有真正计算重叠出现,也不关心空子字符串。
例如:
>>> a = 'caatatab'
>>> b = 'ata'
>>> print(a.count(b)) #overlapping
1
>>>print(a.count('')) #empty string
9
如果我们考虑重叠的子字符串,第一个答案应该是2
而不是1
。
至于第二个答案,最好是空子字符串返回 0 作为 asnwer。
下面的代码会处理这些事情。
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
【讨论】:
【参考方案30】:重叠出现:
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
【讨论】:
以上是关于计算字符串中子字符串出现的次数的主要内容,如果未能解决你的问题,请参考以下文章