Как я могу заменить первое вхождение символа в каждом слове?

44

Как я могу заменить первое вхождение символа в каждом слове?

Скажем, у меня есть эта строка:

hello @jon i am @@here or @@@there and want some@thing in '@here"
#     ^         ^^        ^^^                   ^          ^ 

И я хочу удалить первое @в каждом слове, чтобы в итоге я получил окончательную строку, подобную этой:

hello jon i am @here or @@there and want something in 'here
#     ^        ^        ^^                   ^         ^

Просто для пояснения, символы «@» всегда появляются вместе в каждом слове, но могут находиться в начале слова или между другими символами.

Мне удалось удалить символ «@», если он встречается только один раз, с помощью варианта регулярного выражения, найденного в подстроке Delete, когда это происходит один раз, но не дважды в строке в python , который использует отрицательный прогноз и отрицательный просмотр:

@(?!@)(?<!@@)

Смотрите вывод:

>>> s = "hello @jon i am @@here or @@@there and want some@thing in '@here"
>>> re.sub(r'@(?!@)(?<!@@)', '', s)
"hello jon i am @@here or @@@there and want something in 'here"

Таким образом, следующий шаг - заменить символ «@», если он встречается более одного раза. Это легко сделать, s.replace('@@', '@')удалив символ «@», где бы он ни появлялся снова.

Тем не менее, мне интересно: есть ли способ сделать эту замену за один выстрел?

Федорки "ТАК прекратить вредить"
источник
1
Вам нужен строго регулярный ответ?
Саяндип Датта
@SayandipDutta в принципе, да, но мне также было бы любопытно увидеть другие способы сделать то же самое без регулярных выражений :)
fedorqui 'ТАК ХОЧЕТ вредить'
Просто чтобы убедиться, может ли быть строка вроде: @Hello@Thereгде @бы не быть последовательным?
JVDV
1
@ JvdV нет, такого не будет.
Федорки "ТАК прекрати вредить"

Ответы:

51

Я бы сделал замену регулярного выражения по следующей схеме:

@(@*)

А затем просто замените на первую группу захвата, которая является непрерывными символами @, минус один.

Это должно охватывать каждое @вхождение в начале каждого слова, будь то слово в начале, середине или конце строки.

inp = "hello @jon i am @@here or @@@there and want some@thing in '@here"
out = re.sub(r"@(@*)", '\\1', inp)
print(out)

Это печатает:

hello jon i am @here or @@there and want something in 'here
Тим Бигелейзен
источник
35

Как насчет использования replace('@', '', 1)в выражении генератора?

string = 'hello @jon i am @@here or @@@there and want some@thing in "@here"'
result = ' '.join(s.replace('@', '', 1) for s in string.split(' '))

# output: hello jon i am @here or @@there and want something in "here"

Значение int 1является необязательным countаргументом.

str.replace(old, new[, count])

Вернуть копию строки, в которой все вхождения подстроки old заменены на new . Если указан необязательный аргумент count , заменяются только первые вхождения count .

парень
источник
5
Это умный трюк! Поскольку третий параметр замены - это replace(search, replace, max_matches), он просто заменяет первый в каждом слове.
Федорки "ТАК прекрати вредить"
1
@ fedorqui 'SOstopharming' да, это называется count, я добавил описание из документации.
Парень
2
Остерегайтесь этого побочного эффекта: если у вас есть несколько пробелов (''), они будут потеряны и заменены одним ''.
Марк Ванхомиссен
4

Вы можете использовать , re.subкак это:

import re

s = "hello @jon i am @@here or @@@there and want some@thing in '@here"
s = re.sub('@(\w)', r'\1', s)
print(s)

Это приведет к:

"hello jon i am @here or @@there and want something in 'here"

А вот и подтверждение концепции:

>>> import re
>>> s = "hello @jon i am @@here or @@@there and want some@thing in '@here"
>>> re.sub('@(\w)', r'\1', s)
"hello jon i am @here or @@there and want something in 'here"
>>> 
accdias
источник
2

Задумывался над случаями: что, если только последний символ есть @и вы не хотите его удалять, или у вас есть определенные разрешенные начальные символы, придумал это:

>>> ' '.join([s_.replace('@', '', 1) if s_[0] in ["'", "@"] else s_ for s_ in s.split()])
"hello jon i am @here or @@there and want some@thing in 'here"

Или, предположим, вы хотите заменить, @только если он в первых n символов

>>> ' '.join([s_.replace('@', '', 1) if s_.find('@') in range(2) else s_ for s_ in s.split()])
"hello jon i am @here or @@there and want some@thing in 'here"
Саяндип Датта
источник
2

DEMO

(?<!@)@

Вы можете попробовать это. Смотрите демо.

VKS
источник
1
# Python3 program to remove the @ from String


def ExceptAtTheRate(string):
    # Split the String based on the space
    arrOfStr = string.split()

    # String to store the resultant String
    res = ""

    # Traverse the words and
    # remove the first @ From every word.
    for a in arrOfStr:
        if(a[0]=='@'):
            res += a[1:len(a)] + " "
        else:
            res += a[0:len(a)] + " "

    return res


# Driver code
string = "hello @jon i am @@here or @@@there and want some@thing in '@here"

print(ExceptAtTheRate(string))

Вывод:

введите описание изображения здесь

Амар Кумар
источник
Спасибо! Обратите внимание, что @ в пределах некоторой @ вещи и '@ здесь также должны быть удалены в соответствии с моими требованиями.
Федорки 'ТАК прекрати вредить'