在 Python 中的字符串中查找某个字符串的多次出现[重复]

2025-02-20 09:24:00
admin
原创
72
摘要:问题描述:如何在 Python 中的字符串中查找某个字符串的多次出现?考虑一下:>>> text = "Allowed Hello Hollow" >>> text.find("ll") 1 >>> 因此,正如预期...

问题描述:

如何在 Python 中的字符串中查找某个字符串的多次出现?考虑一下:

>>> text = "Allowed Hello Hollow"
>>> text.find("ll")
1
>>> 

因此,正如预期的那样, 的第一次出现位置ll为 1。我如何找到它的下一次出现位置?

同样的问题也适用于列表。考虑一下:

>>> x = ['ll', 'ok', 'll']

我如何ll通过索引找到所有内容?


解决方案 1:

使用正则表达式,您可以用来re.finditer查找所有(不重叠的)出现情况:

>>> import re
>>> text = 'Allowed Hello Hollow'
>>> for m in re.finditer('ll', text):
         print('ll found', m.start(), m.end())

ll found 1 3
ll found 10 12
ll found 16 18

或者,如果您不想使用正则表达式,您也可以重复使用str.find来获取下一个索引:

>>> text = 'Allowed Hello Hollow'
>>> index = 0
>>> while index < len(text):
        index = text.find('ll', index)
        if index == -1:
            break
        print('ll found at', index)
        index += 2 # +2 because len('ll') == 2

ll found at  1
ll found at  10
ll found at  16

这也适用于列表和其他序列。

解决方案 2:

我认为你要找的是string.count

"Allowed Hello Hollow".count('ll')
>>> 3

希望这有帮助

注意:这只捕获不重叠的事件

解决方案 3:

对于列表示例,使用理解:

>>> l = ['ll', 'xx', 'll']
>>> print [n for (n, e) in enumerate(l) if e == 'll']
[0, 2]

对于字符串也类似:

>>> text = "Allowed Hello Hollow"
>>> print [n for n in xrange(len(text)) if text.find('ll', n) == n]
[1, 10, 16]

这将列出“ll”的相邻运行,这可能是也可能不是你想要的:

>>> text = 'Alllowed Hello Holllow'
>>> print [n for n in xrange(len(text)) if text.find('ll', n) == n]
[1, 2, 11, 17, 18]

解决方案 4:

值得一提的是,这里有几个非 RE 的替代方案,我认为它们比poke 的解决方案更简洁。

第一个用途str.index和检查ValueError

def findall(sub, string):
    """
    >>> text = "Allowed Hello Hollow"
    >>> tuple(findall('ll', text))
    (1, 10, 16)
    """
    index = 0 - len(sub)
    try:
        while True:
            index = string.index(sub, index + len(sub))
            yield index
    except ValueError:
        pass

第二个测试使用并str.find检查哨兵:-1`iter`

def findall_iter(sub, string):
    """
    >>> text = "Allowed Hello Hollow"
    >>> tuple(findall_iter('ll', text))
    (1, 10, 16)
    """
    def next_index(length):
        index = 0 - length
        while True:
            index = string.find(sub, index + length)
            yield index
    return iter(next_index(len(sub)).next, -1)

要将这些函数中的任何一个应用于列表,元组或其他可迭代的字符串,您可以使用更高级别的函数(将函数作为其参数之一的函数),如下所示:

def findall_each(findall, sub, strings):
    """
    >>> texts = ("fail", "dolly the llama", "Hello", "Hollow", "not ok")
    >>> list(findall_each(findall, 'll', texts))
    [(), (2, 10), (2,), (2,), ()]
    >>> texts = ("parallellized", "illegally", "dillydallying", "hillbillies")
    >>> list(findall_each(findall_iter, 'll', texts))
    [(4, 7), (1, 6), (2, 7), (2, 6)]
    """
    return (tuple(findall(sub, string)) for string in strings)

解决方案 5:

对于第一个版本,检查字符串:

def findall(text, sub):
    """Return all indices at which substring occurs in text"""
    return [
        index
        for index in range(len(text) - len(sub) + 1)
        if text[index:].startswith(sub)
    ]

print(findall('Allowed Hello Hollow', 'll'))
# [1, 10, 16]

无需导入re。这应该在线性时间内运行,因为它只循环遍历字符串一次(一旦剩余的字符不足以容纳子字符串,就会在结束前停止)。我个人也发现它非常易读。

请注意,这将发现重叠的发生:

print(findall('aaa', 'aa'))
# [0, 1]

解决方案 6:

对于您的列表示例:

In [1]: x = ['ll','ok','ll']

In [2]: for idx, value in enumerate(x):
   ...:     if value == 'll':
   ...:         print idx, value       
0 ll
2 ll

如果您想要列表中包含“ll”的所有项目,您也可以这样做。

In [3]: x = ['Allowed','Hello','World','Hollow']

In [4]: for idx, value in enumerate(x):
   ...:     if 'll' in value:
   ...:         print idx, value
   ...:         
   ...:         
0 Allowed
1 Hello
3 Hollow

解决方案 7:

该代码可能不是最短/最有效的,但它简单易懂

def findall(f, s):
    l = []
    i = -1
    while True:
        i = s.find(f, i+1)
        if i == -1:
            return l
        l.append(s.find(f, i))

findall('test', 'test test test test')
# [0, 5, 10, 15]

解决方案 8:

>>> for n,c in enumerate(text):
...   try:
...     if c+text[n+1] == "ll": print n
...   except: pass
...
1
10
16

解决方案 9:

此版本应与字符串的长度呈线性关系,并且只要序列不是太重复就应该没问题(在这种情况下,您可以用 while 循环替换递归)。

def find_all(st, substr, start_pos=0, accum=[]):
    ix = st.find(substr, start_pos)
    if ix == -1:
        return accum
    return find_all(st, substr, start_pos=ix + 1, accum=accum + [ix])

bstpierre 的列表理解对于短序列来说是一个很好的解决方案,但看起来具有二次复杂度并且从未在我使用的长文本上完成。

findall_lc = lambda txt, substr: [n for n in xrange(len(txt))
                                   if txt.find(substr, n) == n]

对于非平凡长度的随机字符串,这两个函数给出相同的结果:

import random, string; random.seed(0)
s = ''.join([random.choice(string.ascii_lowercase) for _ in range(100000)])

>>> find_all(s, 'th') == findall_lc(s, 'th')
True
>>> findall_lc(s, 'th')[:4]
[564, 818, 1872, 2470]

但二次版本大约慢 300 倍

%timeit find_all(s, 'th')
1000 loops, best of 3: 282 µs per loop

%timeit findall_lc(s, 'th')    
10 loops, best of 3: 92.3 ms per loop

解决方案 10:

以下函数查找一个字符串在另一个字符串内出现的所有位置,同时告知每个出现的位置。

您可以使用下表中的测试用例来调用该函数。您可以尝试将单词、空格和数字混合在一起。

该功能对于重叠字符很有效。

theStringaString
"661444444423666455678966""55"
"661444444423666455678966""44"
"6123666455678966""666"
"66123666455678966""66"

调用示例:

1. print("Number of occurrences: ", find_all("123666455556785555966", "5555"))
   
   output:
           Found in position:  7
           Found in position:  14
           Number of occurrences:  2
   
2. print("Number of occurrences: ", find_all("Allowed Hello Hollow", "ll "))

   output:
          Found in position:  1
          Found in position:  10
          Found in position:  16
          Number of occurrences:  3

3. print("Number of occurrences: ", find_all("Aaa bbbcd$#@@abWebbrbbbbrr 123", "bbb"))

   output:
         Found in position:  4
         Found in position:  21
         Number of occurrences:  2
         

def find_all(theString, aString):
    count = 0
    i = len(aString)
    x = 0

    while x < len(theString) - (i-1): 
        if theString[x:x+i] == aString:        
            print("Found in position: ", x)
            x=x+i
            count=count+1
        else:
            x=x+1
    return count

解决方案 11:

编程新手,正在学习在线教程。我也被要求这样做,但只使用我迄今为止学到的方法(基本上是字符串和循环)。不确定这是否会在这里增加任何价值,我知道这不是你这样做的方式,但我让它与此一起工作:

needle = input()
haystack = input()
counter = 0
n=-1
for i in range (n+1,len(haystack)+1):
   for j in range(n+1,len(haystack)+1):
      n=-1
      if needle != haystack[i:j]:
         n = n+1
         continue
      if needle == haystack[i:j]:
         counter = counter + 1
print (counter)

解决方案 12:

#!/usr/local/bin python3
#-*- coding: utf-8 -*-

main_string = input()
sub_string = input()

count = counter = 0

for i in range(len(main_string)):
    if main_string[i] == sub_string[0]:
        k = i + 1
        for j in range(1, len(sub_string)):
            if k != len(main_string) and main_string[k] == sub_string[j]:
                count += 1
                k += 1
        if count == (len(sub_string) - 1):
            counter += 1
        count = 0

print(counter) 

此程序无需使用正则表达式即可计算所有子字符串的数量,即使它们重叠。但这是一种简单的实现,为了在最坏情况下获得更好的结果,建议使用后缀树、KMP 和其他字符串匹配数据结构和算法。

解决方案 13:

下面是我用于查找多个出现的函数。与此处的其他解决方案不同,它支持切片的可选开始和结束参数,就像str.index

def all_substring_indexes(string, substring, start=0, end=None):
    result = []
    new_start = start
    while True:
        try:
            index = string.index(substring, new_start, end)
        except ValueError:
            return result
        else:
            result.append(index)
            new_start = index + len(substring)

解决方案 14:

一个简单的迭代代码,它返回子字符串出现的索引列表。

        def allindices(string, sub):
           l=[]
           i = string.find(sub)
           while i >= 0:
              l.append(i)
              i = string.find(sub, i + 1)
           return l

解决方案 15:

您可以拆分以获取相对位置,然后对列表中的连续数字求和并同时添加(字符串长度*出现顺序)以获取所需的字符串索引。

>>> key = 'll'
>>> text = "Allowed Hello Hollow"
>>> x = [len(i) for i in text.split(key)[:-1]]
>>> [sum(x[:i+1]) + i*len(key) for i in range(len(x))]
[1, 10, 16]
>>> 

解决方案 16:

也许不是那么 Pythonic,但更不言自明。它返回在原始字符串中查找的单词的位置。

def retrieve_occurences(sequence, word, result, base_counter):
     indx = sequence.find(word)
     if indx == -1:
         return result
     result.append(indx + base_counter)
     base_counter += indx + len(word)
     return retrieve_occurences(sequence[indx + len(word):], word, result, base_counter)

解决方案 17:

我认为没有必要测试文本的长度;只需继续查找,直到找不到任何内容。像这样:

    >>> text = 'Allowed Hello Hollow'
    >>> place = 0
    >>> while text.find('ll', place) != -1:
            print('ll found at', text.find('ll', place))
            place = text.find('ll', place) + 2


    ll found at 1
    ll found at 10
    ll found at 16

解决方案 18:

您还可以使用条件列表理解来实现这一点,如下所示:

string1= "Allowed Hello Hollow"
string2= "ll"
print [num for num in xrange(len(string1)-len(string2)+1) if string1[num:num+len(string2)]==string2]
# [1, 10, 16]

解决方案 19:

不久前我偶然想到了这个想法。使用 While 循环进行字符串拼接和字符串搜索是可行的,即使对于重叠的字符串也是如此。

findin = "algorithm alma mater alison alternation alpines"
search = "al"
inx = 0
num_str = 0

while True:
    inx = findin.find(search)
    if inx == -1: #breaks before adding 1 to number of string
        break
    inx = inx + 1
    findin = findin[inx:] #to splice the 'unsearched' part of the string
    num_str = num_str + 1 #counts no. of string

if num_str != 0:
    print("There are ",num_str," ",search," in your string.")
else:
    print("There are no ",search," in your string.")

我是 Python 编程(实际上是任何语言的编程)的业余爱好者,不确定它可能还存在什么其他问题,但我猜它运行良好?

我想,如果需要的话,lower() 也可以在其中的某个地方使用。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3958  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2737  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   74  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   83  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   70  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用