如何解决获取替换子字符串的所有可能组合 1将字符串分隔为单词列表 2找到您要替换的单词的索引 3创建这些索引的幂集 4遍历幂集并替换每个集的索引中的单词完整代码
给定子字符串和任意替换的Python文本组合
"foo bar foo foo"
并给定该字符串中的一个子字符串,例如:"foo"
我想获得将每个"foo"
替换为某个任意字符串(长度可能不同)的所有组合。
例如:
>>> combinations("foo bar foo foo","foo","fooer")
{
"foo bar foo foo","fooer bar foo foo","foo bar fooer foo","foo bar foo fooer","fooer bar fooer foo","fooer bar foo fooer","fooer bar fooer fooer","foo bar fooer fooer",}
我已经搜索过,找不到任何可以帮助我的东西。
我知道我必须对组合使用itertools.product
,但是当同一字符串中出现多个外观并且子字符串及其替换长度不同时,我会陷入困境。
当我得到必须开始替换的索引时:
def indices_substring(a_str,sub):
"""https://stackoverflow.com/a/4665027/9288003"""
start = 0
while True:
start = a_str.find(sub,start)
if start == -1: return
yield start
start += len(sub) # use start += 1 to find overlapping matches
解决方法
您可以遵循以下食谱:
- 将字符串分隔为单词列表。
- 找到要替换的单词的索引。
- 创建这些索引的幂集。
- 遍历幂集并替换每个索引集中的单词。
1。将字符串分隔为单词列表
对任何Python用户来说都足够简单:
words = "foo bar foo foo".split()
如果字符串不一定要用空格分隔,则可以使用regex:
import re
words = re.split("(foo)","foobarfoofoo")
2。找到您要替换的单词的索引
这可以通过非常简单的列表理解来完成:
indices = [i for i,v in enumerate(words) if v == "foo"]
3。创建这些索引的幂集
itertools
Recipes page官方提供了一套电源:
from itertools import chain,combinations
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,3)"
s = list(iterable)
return chain.from_iterable(combinations(s,r) for r in range(len(s)+1))
因此使用此功能,此步骤非常简单:
power_set = powerset(indices)
4。遍历幂集并替换每个集的索引中的单词
为此,我们将首先创建words
列表的副本以进行处理,然后简单地从powerset迭代每个项目的索引,并替换这些索引中的单词。最后,我们将join
列出:
for replacements in powerset(indices):
new_words = list(words)
for index in replacements:
new_words[index] = "fooer"
print(" ".join(new_words))
*(如果使用正则表达式版本),则应为''.join(...)
完整代码
所有这些看起来像:
from itertools import chain,r) for r in range(len(s)+1))
s = "foo bar foo foo"
to_find = "foo"
to_replace = "fooer"
words = s.split()
# regex: words = re.split(f"({to_find})",s)
indices = [i for i,v in enumerate(words) if v == to_find]
for replacements in powerset(indices):
new_words = list(words)
for index in replacements:
new_words[index] = to_replace
print(" ".join(new_words))
# regex: print(''.join(new_words))
哪个给:
foo bar foo foo
fooer bar foo foo
foo bar fooer foo
foo bar foo fooer
fooer bar fooer foo
fooer bar foo fooer
foo bar fooer fooer
fooer bar fooer fooer
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。