#python #regex #string
Вопрос:
В Python я пытаюсь очистить (а затем сравнить) имена исполнителей и хочу удалить:
- не альфа-символы, или
- пробелы, или
- слово «и»
СТРОКА ВВОДА: Bootsy Collins and The Rubber Band
ЖЕЛАЕМЫЙ РЕЗУЛЬТАТ: BootsyCollinsTheRubberBand
import re
s = 'Bootsy Collins and The Rubber Band'
res1 = re.sub(r'[^w]|s|s (and)s', "", s)
res2 = re.sub(r'[^w]|s|sands', "", s)
res3 = re.sub(r'[^w]|s|(and)', "", s)
print("b", s, "n"
, "1st: ", res1, "n"
, "2nd: ", res2, "n"
, "3rd: ", res3)
Output:
Bootsy Collins and The Rubber Band
1st: BootsyCollinsandTheRubberBand
2nd: BootsyCollinsandTheRubberBand
3rd: BootsyCollinsTheRubberB
Комментарии:
1. Регулярное выражение решения, представленное в ответах здесь, должно работать также для других типов/разновидностей регулярных выражений (например, PCRE, ECMAScript, Golang, java). Тем не менее, заголовок и содержание вопроса были добавлены с учетом специфики используемого синтаксиса Python. Это делается для того, чтобы люди, знакомые с другими регулярными выражениями других языков, не могли неправильно истолковать этот вопрос, вызванный опечаткой, и не считали его невоспроизводимым.
Ответ №1:
Для поддержки правил, которые вы изложили, вместо того, чтобы просто цитировать образец текста, вам нужно более общее регулярное выражение с правильной настройкой флагов для re.sub
вызова:
re.sub(r'bandb|W', '', s, flags=re.IGNORECASE)
Объяснение
- Флаг
re.IGNORECASE
установлен таким образом, чтобы вы также могли удалить «И» (и другие варианты сочетания прописных/строчных букв) в предложении. В случае, если вы хотите удалить только «и», но не какие-либо его варианты, вы можете удалить этот параметр флага. bandb
слово «и», заключенное в знак границы словаb
с обеих сторон. Это должно соответствовать последовательности из 3 символов «и» как независимому слову, а не как подстроке другого слова. Использованиеb
для изоляции слова вместо того, чтобы заключать слово в пробелы, напримерs ands
, имеет то преимущество, чтоb
опция также может определять границу слова в строках, напримерand,
, покаs ands
не может этого сделать. Это происходит потому, что запятая-это не пробел.- Поскольку пробел
s
также является своего рода не-словомW
(поскольку словоw
эквивалентно[a-zA-Z0-9_]
), вам не нужны отдельные токены регулярного выражения для обоих.W
уже включаетs
в себя . Таким образом, вы можете упростить регулярное выражение без отдельного использованияs
.
ДЕМОНСТРАЦИЯ
Тестовый случай № 1:
s = 'Bootsy Collins and The Rubber Band'
res = re.sub(r'bandb|W', '', s, flags=re.IGNORECASE)
print(res)
Output:
'BootsyCollinsTheRubberBand'
Тестовый случай № 2 («И» удалено) :
s = 'Bootsy Collins And The Rubber Band'
res = re.sub(r'bandb|W', '', s, flags=re.IGNORECASE)
print(res)
Output:
'BootsyCollinsTheRubberBand'
Тестовый случай № 3 («и» [с запятой после «и»] удален)
s = 'Bootsy Collins and, The Rubber Band'
res = re.sub(r'bandb|W', '', s, flags=re.IGNORECASE)
print(res)
Output:
'BootsyCollinsTheRubberBand'
Тестовый пример счетчика: (регулярное выражение с использованием пробела s
или s
вместо b
границы слова)
s = 'Bootsy Collins and, The Rubber Band'
res = re.sub(r's (and)s|W', '',s)
print(res)
Output: 'and' is NOT removed
'BootsyCollinsandTheRubberBand'
Ответ №2:
Ваши первые два регулярных выражения не соответствуют «и», потому что при достижении этой позиции в строке s
часть регулярного выражения будет соответствовать пробелу перед «и» вместо s (and)s
части вашего регулярного выражения.
Вам просто нужно изменить порядок, чтобы сначала было опробовано последнее. Кроме того, s
является частью [^w]
, поэтому вам не нужно сопоставлять s
отдельно. И, наконец, W
является более короткой формой [^w]
. Так что используйте:
s (and)s|W