哪种方法可以找到模式在给定字符串中的所有出现的列表?
问题的提出
问题的提出:给定一个长字符串和一个短字符串。如何找到短字符串在长字符串中的所有出现?
请看下面的例子。
- 较长的字符串。
'Finxters learn Python with Finxter' - 较短的字符串模式。
'Finxter' - 结果1:
['Finxter', 'Finxter']
作为选择,你可能还想得到短字符串在长字符串中出现的位置。
- 结果2:
[(0, 'Finxter'), (27, 'Finxter')]
方法1:Regex re.finditer()
要获得一个模式在给定字符串中的所有出现,你可以使用正则表达式方法 [re.finditer(pattern, string)](https://blog.finxter.com/python-regex-finditer/ "Python Regex Finditer()").其结果是一个匹配对象的迭代器--你可以使用match.start() 和match.end() 函数检索匹配的索引。
import re
s = 'Finxters learn Python with Finxter'
pattern = 'Finxter'
# Method 1: re.finditer
for m in re.finditer(pattern, s):
print(pattern, 'matched from position', m.start(), 'to', m.end())
输出结果是:
Finxter matched from position 0 to 7
Finxter matched from position 27 to 34
方法2:re.finditer() + 列表理解
为了将匹配的模式字符串、开始索引和结束索引变成一个图元的列表,你可以使用以下基于列表理解的单行代码。
[(pattern, m.start(), m.end()) for m in re.finditer(pattern, s)].
import re
s = 'Finxters learn Python with Finxter'
pattern = 'Finxter'
# Method 2: re.finditer + list comprehension
l = [(pattern, m.start(), m.end()) for m in re.finditer(pattern, s)]
print(l)
其输出结果是:
[('Finxter', 0, 7), ('Finxter', 27, 34)]
方法3:Python字符串 startswith()
Pythonstartswith(prefix, start) 方法在开始搜索索引prefix 时,检查给定的字符串是否以前缀开始start 。
我们可以在一个列表理解语句中使用startswith() 方法,像这样找到一个给定字符串中子串的所有出现(位置)。
[i for i in range(len(s)) if s.startswith(pattern, i)]
下面是使用这种方法的完整例子。
s = 'Finxters learn Python with Finxter'
pattern = 'Finxter'
# Method 4: startswith() to find all occurrences of substring in string
l = [i for i in range(len(s)) if s.startswith(pattern, i)]
print(l)
输出显示了在原始字符串中发现子串(模式)的起始索引列表。
[0, 27]
方法4:re.findall()
如果你只对给定字符串中没有索引位置的匹配子串感兴趣,你可以使用以下方法。
要找到给定字符串中的所有子串,可以使用re.findall(substring, string) ,该函数返回一个匹配子串的列表--每个匹配子串。
import re
s = 'Finxters learn Python with Finxter'
pattern = 'Finxter'
# Method 4: re.findall() to find all patterns in string
l = re.findall(pattern, s)
print(l)
# ['Finxter', 'Finxter']
如果你想知道regex.findall() 方法是如何工作的,可以看一下这个图形。

方法5:无REGEX,递归,重叠
下面这个方法是基于递归的,它不需要任何外部库。
我们的想法是反复寻找字符串中下一个出现的子串模式,并在一个较短的字符串上递归调用相同的方法--将起始位置向右移动,直到再也找不到匹配的字符串。
当你通过递归调用时,所有找到的子串匹配都累积在一个变量中acc 。
s = 'Finxters learn Python with Finxter'
pattern = 'Finxter'
# Method 5: recursive, without regex
def find_all(pattern, # string pattern
string, # string to be searched
start=0, # ignore everything before start
acc=[]): # All occurrences of string pattern in string
# Find next occurrence of pattern in string
i = string.find(pattern, start)
if i == -1:
# Pattern not found in remaining string
return acc
return find_all(pattern, string, start = i+1,
acc = acc + [(pattern, i)]) # Pass new list with found pattern
l = find_all(pattern, s)
print(l)
输出结果是。
[('Finxter', 0), ('Finxter', 27)]
请注意,这个方法也可以找到重叠的匹配--与消耗所有部分匹配的子串的regex方法不同。