Python字符串替换行为异常

2024-09-27 07:31:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图得到谁是在一篇文章中提到的用户。也就是说,单词以@符号开头,然后环绕<>。你知道吗

我尝试的:

def getUsers(content):
    users = []
    l = content.split(' ')
    for user in l:
        if user.startswith('@'):
            users.append(user)
    return users

old_string = "Getting and replacing mentions of users. @me @mentee @you @your @us @usa @wo @world @word @wonderland"

users = getUsers(old_string)

new_array = old_string.split(' ')

for mention in new_array:
    for user in users:
        if mention == user and len(mention) == len(user):
            old_string = old_string.replace(mention, '<' + user + '>')

print old_string
print users

代码的行为很滑稽。它将以相同字母开头的单词包装起来,甚至将随后的单词截断,如下图所示:

结果:

Getting and replacing mentions of users. <@me> <@me>ntee <@you> <@you>r <@us> <@us>a <@wo> <@wo>rld <@wo>rd <@wo>nderland
['@me', '@mentee', '@you', '@your', '@us', '@usa', '@wo', '@world', '@word', '@wonderland']

预期结果:

Getting and replacing mentions of users. <@me> <@mentee> <@you> <@your> <@us> <@usa> <@wo> <@world> <@word> <@wonderland>
['@me', '@mentee', '@you', '@your', '@us', '@usa', '@wo', '@world', '@word', '@wonderland']

Process finished with exit code 0

为什么会发生这种情况?如何才能正确地做到这一点?你知道吗


Tags: andyouworldyourstringusersoldword
3条回答

为什么会发生这种情况:当您拆分字符串时,您会进行大量检查以确保您看到的是正确的用户,例如,您有@me@mentee-因此对于用户me,它将匹配第一个,而不是第二个。你知道吗

然而,当你做替换时,你是在整个字符串上做替换-所以当你说用<@me>替换例如@me时,它对你的小心拆分一无所知-它只是在字符串中寻找@me并替换它。所以@mentee也包含@me,并且将被替换。你知道吗

两个(好吧,三个)选择:一个是在它周围加上空格,把它关起来(就像@parchent写的那样)。你知道吗

第二种方法是使用split:替换本地片段,而不是替换原始字符串。最简单的方法是使用枚举:

new_array = old_string.split(' ')

for index, mention in enumerate(new_array):
    for user in users:
        if mention == user and len(mention) == len(user):
            #We won't replace this in old_string, we'll replace the current entry
            #old_string = old_string.replace(a, '<' + user + '>')
            new_array[index] = '<%s>'%user

new_string = ' '.join(new_array)

第三条路。。。这有点复杂,但您真正想要的是将'@anything'的任何实例替换为<@anything>(可能是空白?)。您可以使用re.sub一次性完成此操作:

new_string = re.sub(r'(@\w+)', r'<\g<0>>', old_string)

我以前的回答完全是基于纠正当前代码中的问题。但是,有一个更好的方法可以做到这一点,那就是使用正则表达式。你知道吗

import re

oldstring = re.sub(r'(@\w+)\b', r'<\1>', oldstring)

有关更多信息,请参阅^{}模块的文档。你知道吗

因为@me首先出现在数组中,所以代码将替换@mentee中的@me。你知道吗

最简单的解决方法是在要替换的用户名后添加空格:

old_string = old_string.replace(a + ' ', '<' + user + '> ')
                # I added space here ^         and here ^

不过,出现了一个新问题。最后一个单词没有包装,因为后面没有空格。一个非常简单的解决方法是:

oldstring = oldstring + ' '

for mention in ... # Your loop

oldstring = oldstring[:-1]

相关问题 更多 >

    热门问题