在字符串中查找两个或多个相同类型的字符?

时间:2013-08-03 19:17:47

标签: python string-matching

我正在编写一段代码,需要在单词中找到某些字符,然后在生成的字符串中替换这些字符。当单词只包含每个字符中的一个时,代码工作正常;但是,当我有两个或更多相同类型的字符时,代码只识别第一个字符并忽略以下字符。您对如何解决此问题有任何建议吗?

def write_words(word,al):

newal = (list(al))
n = len(word)
i = 0
x = 0
a = []
b = ["_"]
for i in range(0, n):
    a = a + b
while (x <(len(newal))):
    z = newal[x]
    y = word.find(z)
    x = x + 1
    print (y)
    if y >= 0:
        a[y] = z
return(a)

(我正在使用的Python版本是3.2.1)

3 个答案:

答案 0 :(得分:1)

这里的问题是find()返回元素第一次出现的索引。

您只需使用以下代码替换匹配项。

>>> word = 'abcdabcd'
>>> ignore = 'ab'
>>> "".join([elem if elem not in ignore else '_' for elem in word])
'__cd__cd'

P.S - 关于您当前代码的一些指示。

def write_words (word, al):
    newal = (list(al))
    n = len(word)
    i = 0
    x = 0
    a = []
    b = ["_"]
    for i in range(0, n):
        a = a + b
    while (x <(len(newal))):
        z = newal[x]
        y = word.find(z)
        x = x + 1
        print (y)
        if y >= 0:
            a[y] = z
    return(a)
  1. 您可以刚刚完成for,而不是_循环并将a = ['_']*len(word)添加到a​​中的每个元素。
  2. 您不需要在此处使用while循环或将您的单词转换为list。字符串是可迭代的,因此您可以for elem in newal。这样,您就不必保留单独的x变量来迭代字符串。
  3. 所以,现在你的代码被缩减为

    >>> def write_words_two(word, al):
            a = ['_']*len(word)
            for elem in al:
                y = word.find(elem)
                print(y)
                a[y] = z
            return a
    

    但是,它仍然存在与以前相同的问题。现在问题似乎是word.find(elem)只返回第一个字符的出现而不是所有出现的索引。所以,不是先建立一个列表然后替换字符,我们应该在我们进行时建立列表并测试我们忽略的字符的每个字符,如果字符需要被忽略,我们只需用它的替换替换它在列表中。然后,我们提出以下代码

    >>> def write_words_three(word, al, ignore):
            a = []
            for elem in word:
                if elem in al:
                    a.append(ignore)
                else:
                    a.append(elem)
            return a
    
    >>> write_words_three('abcdabcd', 'ab', '_')
    ['_', '_', 'c', 'd', '_', '_', 'c', 'd']
    

    但是,它仍然似乎返回列表而不是字符串,这就是我们想要的,而且它似乎也有点大。那么,为什么不用列表理解来缩短呢?

    >>> def write_words_four(word, al, ignore):
            return [elem if elem not in al else ignore for elem in word]
    
    >>> write_words_threefour('abcdabcd', 'ab', '_')
    ['_', '_', 'c', 'd', '_', '_', 'c', 'd']
    

    我们仍然需要一个字符串,我们的代码只返回一个列表。我们可以使用join(...)方法并连接字符串的每个元素。

    >>> def write_words_five(word, al, ignore):
            return "".join([elem if elem not in al else ignore for elem in word])
    
    >>> write_words_five('abcdabcd', 'ab', '_')
    '__cd__cd'
    

    它给了我们想要的东西。

答案 1 :(得分:0)

将此find功能替换为:

def myfind(main, x):
    return [i for i,j in enumerate(x) if j==x]

以便在您的代码中:

ys = myfind( word, z )
for y in ys:
    a[y] = z

答案 2 :(得分:0)

这应该做OP所要求的,对原始代码的改动很小。如果“_”是al。

中允许的字符,则不起作用
def write_words (word, al):
    newal = (list(al))
    n = len(word)
    i = 0
    x = 0
    a = []
    b = ["_"]
    for i in range(0, n):
        a = a + b
    while (x <(len(newal))):
        z = newal[x]
        y = word.find(z)
        while (y >= 0):
            print (y)
            a[y] = z
            word[y] = "_"
            y = word.find(z)
        x = x + 1
    return a