5

我有这个初始字符串。

'bananaappleorangestrawberryapplepear'

还有一个带字符串的元组:

('apple', 'plepe', 'leoran', 'lemon')

我想要一个函数,以便从初始字符串和带字符串的元组中获得:

'bananaxxxxxxxxxgestrawberryxxxxxxxar'

我知道如何通过在每个单词的初始字符串中找到单词,然后在所有初始字符串中逐个字符地循环替换单词来强制执行此操作。

但这不是很有效和丑陋。我怀疑应该有一些更优雅的方法,以功能的方式,使用 itertools 或其他东西。如果您知道可以有效执行此操作的 Python 库,请告诉我。

更新:贾斯汀·皮尔(Justin Peel)指出了一个我在最初的问题中没有描述的案例。如果单词是 'aaa' 并且 'aaaaaa' 在初始字符串中,则输出应类似于 'xxxxxx'。

4

6 回答 6

3
import re

words = ('apple', 'plepe', 'leoran', 'lemon')
s = 'bananaappleorangestrawberryapplepear'

x = set()

for w in words:
    for m in re.finditer(w, s):
        i = m.start()
        for j in range(i, i+len(w)):
            x.add(j)

result = ''.join(('x' if i in x else s[i]) for i in range(len(s)))
print result

产生:

bananaxxxxxxxxxgestrawberryxxxxxxxar
于 2010-11-13T18:36:27.903 回答
1
>>> string_ = 'bananaappleorangestrawberryapplepear'
>>> words = ('apple', 'plepe', 'leoran', 'lemon')
>>> xes = [(string_.find(w), len(w)) for w in words]
>>> xes
[(6, 5), (29, 5), (9, 6), (-1, 5)]
>>> for index, len_ in xes:
...   if index == -1: continue
...   string_ = string_.replace(string_[index:index+len_], 'x'*len_)
...
>>> string_
'bananaxxxxxxxxxgestrawberryxxxxxxxar'
>>>

当然还有更有效的方法,但过早的优化是万恶之源。

于 2010-11-13T22:10:50.263 回答
1

这是另一个答案。可能有一种更快的方法可以用 x 替换字母,但我认为没有必要,因为这已经非常快了。

import re

def do_xs(s,pats):
    pat = re.compile('('+'|'.join(pats)+')')

    sout = list(s)
    i = 0
    match = pat.search(s)
    while match:
        span = match.span()
        sout[span[0]:span[1]] = ['x']*(span[1]-span[0])
        i = span[0]+1
        match = pat.search(s,i)
    return ''.join(sout)

txt = 'bananaappleorangestrawberryapplepear'
pats = ('apple', 'plepe', 'leoran', 'lemon')
print do_xs(txt,pats)

基本上,我创建了一个匹配任何输入模式的正则表达式模式。然后我只是在最近匹配的起始位置之后继续从 1 开始重新开始搜索。如果您有一个输入模式是另一个输入模式的前缀,则可能会出现问题。

于 2010-11-13T19:19:25.450 回答
1

假设我们仅限于在没有 stdlib 和其他导入的情况下工作:

s1 = 'bananaappleorangestrawberryapplepear'
t = ('apple', 'plepe', 'leoran', 'lemon')
s2 = s1

solution = 'bananaxxxxxxxxxgestrawberryxxxxxxxar'

for word in t:
    if word not in s1: continue
    index = -1 # Start at -1 so our index search starts at 0
    for iteration in range(s1.count(word)):
        index = s1.find(word, index+1)
        length = len(word)
        before = s2[:index]
        after = s2[index+length:]
        s2 = before + 'x'*length + after

print s2 == solution
于 2010-11-13T19:42:56.643 回答
0
a = ('apple', 'plepe', 'leoran', 'lemon')
b = 'bananaappleorangestrawberryapplepear'

for fruit in a:
    if a in b:
        b = b.replace(fruit, numberofx's)

您现在唯一要做的就是确定要替换多少个 X。

于 2010-11-13T18:10:43.470 回答
0
def mask_words(s, words):
    mask = [False] * len(s)
    for word in words:
        pos = 0
        while True:
            idx = s.find(word, pos)
            if idx == -1:
                break

            length = len(word)
            for i in xrange(idx, idx+length):
                mask[i] = True
            pos = idx+length

    # Sanity check:
    assert len(mask) == len(s)

    result = []
    for masked, c in zip(mask, s):
        result.append('x' if masked else c)

    return "".join(result)
于 2010-11-13T18:30:06.560 回答