Замена нескольких символов в строке другим символом в Python - PullRequest
0 голосов
/ 01 июля 2019

У меня есть список строк, которые я хочу проверить, содержит ли каждая строка определенные символы; если это так, то замените символы другим символом.

У меня есть что-то вроде ниже:

invalid_chars = [' ', ',', ';', '{', '}', '(', ')', '\\n', '\\t', '=']
word = 'Ad{min > HR'
for c in list(word):
  if c in invalid_chars:
    word = word.replace(c, '_')
print (word) 

>>> Admin_>_HR

Я пытаюсь преобразовать это в функцию, используя понимание списка, но я странный персонаж ...

def replace_chars(word, checklist, char_replace = '_'):
  return ''.join([word.replace(ch, char_replace) for ch in list(word) if ch in checklist])

print(replace_chars(word, invalid_chars))
>>> Ad_min > HRAd{min_>_HRAd{min_>_HR

Ответы [ 3 ]

3 голосов
/ 01 июля 2019

Это может быть полезно для str.translate(). Вы можете превратить ваш invalid_chars в таблицу перевода с помощью str.maketrans() и применять там, где вам это нужно:

invalid_chars = [' ', ',', ';', '{', '}', '(', ')', '\n', '\t', '=']
invalid_table = str.maketrans({k:'_' for k in invalid_chars})

word = 'Ad{min > HR'

word.translate(invalid_table)

Результат:

'Ad_min_>_HR'

Это будет особенно хорошо, если вам нужно применить этот перевод к нескольким строкам и сделать его более эффективным, поскольку вам не нужно перебирать весь массив invalid_chars для каждой буквы, каждый раз, когда вы будете использовать, если вы используете if x in invalid_chars внутри петли.

3 голосов
/ 01 июля 2019

Попробуйте этот общий шаблон:

''.join([ch if ch not in invalid_chars else '_' for ch in word])

Для полной функции:

def replace_chars(word, checklist, char_replace = '_'):
  return ''.join([ch if ch not in checklist else char_replace for ch in word])

Примечание: нет необходимости переносить строку word в list(), она уже повторяется.

2 голосов
/ 01 июля 2019

Это проще с регулярным выражением. Вы можете искать целую группу символов с помощью одного вызова подстановки. Он тоже должен работать лучше.

>>> import re
>>> re.sub(f"[{re.escape(''.join(invalid_chars))}]", "_", word)
'Ad_min_>_HR'

Код в f-строке создает шаблон регулярного выражения, который выглядит следующим образом

>>> pattern = f"[{re.escape(''.join(invalid_chars))}]"
>>> print(repr(pattern))
'[\\ ,;\\{\\}\\(\\)\\\n\\\t=]'
>>> print(pattern)
[\ ,;\{\}\(\)\
\   =]

То есть набор символов регулярных выражений, содержащий каждый из ваших недопустимых символов. (Выход из обратной косой черты гарантирует, что ни один из них не будет интерпретирован как управляющий символ регулярного выражения, независимо от того, какие символы вы вводите в invalid_chars.) Если бы вы указали их как строку в первую очередь, ''.join() не потребовалось бы .

Вы также можете скомпилировать шаблон (используя re.compile()), если вам нужно повторно использовать его для нескольких слов.

...