Python re.sub для удаления одинарных и двойных кавычек из строки

#python #regex #string #re #rawstring

#python #регулярное выражение #строка #python-re #rawstring

Вопрос:

Вот вопрос, который быстро сводит меня с ума. Я хочу удалить оба символа ‘ и » из строки. Я хочу использовать re.sub для этого (потому что я пытаюсь сравнить re.sub с str.replace, поэтому я хочу сделать это обоими способами). Теперь мое понимание необработанных строк заключается в том, что управляющие символы обрабатываются как литералы, ЕСЛИ они не экранируют символ, открывший строку. Итак, у меня есть две идеи, как это сделать:

 # Method 1: concatenate strings that have different enclosing characters
>>> REGEX1 = re.compile(r"["   r'"'   r"'"   r"]")
>>> REGEX1.pattern
'["']'
# Method 2: Try to escape one of the quotation characters
>>> REGEX2= re.compile(r"["']")
>>> REGEX2.pattern
'[\"']'
  

Приведенные шаблоны ВЫГЛЯДЯТ по-другому. Они все же есть? Я проверяю, ведут ли они себя одинаково в регулярном выражении:

 >>> test_string = "hello ' world " "
>>> test_string
'hello ' world " '
>>> result_1 = REGEX1.sub(r'', test_string)
>>> result_2 = REGEX2.sub(r'', test_string)
>>> result_1
'hello  world  '
>>> result_2
'hello  world  '
>>> 
  

Моя интуиция подсказывает мне, что возможно одно из двух:

  1. ‘[«‘]’ == ‘[«‘]’
  2. ‘[«‘]’ != ‘[«‘]’, но будет вести себя эквивалентно, если рассматривать его как регулярное выражение.

Тогда последний тест:

 >>> '["']' == '[\"']'                                                                                                                                                                                      
False
  

Итак, 2) выше правильного утверждения? Можете ли вы помочь мне понять, что происходит?

Ответ №1:

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

 import re


REGEX1 = re.compile(r"["   r'"'   r"'"   r"]")
print(REGEX1.pattern)
print(REGEX1.sub('', """abc"'def"""))
REGEX2= re.compile(r"["']")
print(REGEX2.pattern)
print(REGEX2.sub('', """abc"'def"""))
  

С принтами:

 ["']
abcdef
["']
abcdef 
  

Объяснение

Разница между необработанной строкой r'n' и необработанной строкой 'n' огромна, потому что последняя представляет собой специальную escape-последовательность, которая соответствует символу новой строки, тогда как первая эквивалентна '\n' , т.е. двухсимвольной последовательности обратной косой черты, за которой следует буква n . Но для других случаев, таких как '" , где обратная косая черта, за которой следует двойная кавычка, не является специальной escape-последовательностью, тогда обратная косая черта является излишней и может быть проигнорирована и, следовательно ["'] , ["'] эквивалентна.

Обновить

Поскольку я указал на то, что в целом существует большая разница между escape-последовательностями в необработанных строках и не-необработанных строках, когда то, что следует за обратной косой чертой, имеет особое значение после обратной косой черты (например r'n' , vs 'n' . ), это не всегда так для всех намерений и целей с регулярными выражениями. Например, при использовании в регулярных выражениях механизм регулярных выражений Python сопоставит символ новой строки либо с регулярным выражением, скомпилированным из двухсимвольной последовательности r'n' (то есть '\n' ), либо с символом новой строки 'n' :

 import re


REGEX1 = re.compile('anb') # use actual newline
print('pattern1 = ', REGEX1.pattern)
print(REGEX1.search('anb'))
REGEX2 = re.compile(r'anb') # use '\n'
print('pattern 2 =', REGEX2.pattern)
print(REGEX2.search('anb'))
  

С принтами:

 pattern1 =  a
b
<re.Match object; span=(0, 3), match='anb'>
pattern 2 = anb
<re.Match object; span=(0, 3), match='anb'>
  

Но необработанные строки обычно используются из-за ситуаций, когда вам может потребоваться, например, r'1' вернуться к группе захвата 1 и '1' получить совпадение 'x01' .