Как экранировать специальные символы строки с помощью одной обратной косой черты

python #python-3.x #string #backslash

#python #nginx #экранирование

Вопрос:

Я пытаюсь экранировать символы -]^$*. , каждый из которых имеет одну обратную косую черту.

Например, строка: ^stack.*/overflow$arr=1 станет:

 ^stack.*/overflo\w$arr=1
 

Какой наиболее эффективный способ сделать это в Python?

re.escape двойные экранирования, чего я не хочу:

 '\^stack\.\*\/overflow\$arr\=1'
 

Мне это нужно для экранирования для чего-то другого (nginx).

Ответ №1:

Это один из способов сделать это (в Python 3.x):

 escaped = a_string.translate(str.maketrans({"-":  r"-",
                                          "]":  r"]",
                                          "\": r"\",
                                          "^":  r"^",
                                          "$":  r"$",
                                          "*":  r"*",
                                          ".":  r"."}))
 

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

 import re
escaped = re.escape(a_string)
 

Комментарии:

1. @hcwhsa string.translate как в a_variable_called_string.translate , а не функция, вызываемая translate в строке модуля.

2. Следует отметить, что maketrans находится в python 3, а не в python 2.x

3. maketrans() все еще находится в Python 2. Это в модуле string, а не в объекте str: docs.python.org/2/library/string.html#string.maketrans

4. maketrans в python2 ведет себя совсем по-другому, требуя, чтобы входные и выходные строки были одинаковой длины, и он не принимает ввод по словарю. Это не очень хорошо для выполнения такого рода переводов.

Ответ №2:

Просто предполагая, что это для регулярного выражения, используйте re.escape .

Комментарии:

1. Примечание вместо dv: автор отредактировал вопрос после публикации этого ответа, чтобы уточнить, что re.escape — это не то, что они ищут.

2. @Air: В какой-то момент я рассмотрю точные несовместимости, но у автора вопроса сложилось впечатление, что это не сработало, потому что оно дважды экранировалось, но это было потому, что они использовали его в REPL, и это было repr() . На самом деле он этого не делает и работает в Nginx для приведенного примера.

Ответ №3:

Мы могли бы использовать встроенную функцию repr() или интерполяцию строк fr'{}' , чтобы избежать всех обратных косых черт в Python 3.7.*

repr('my_string') или fr'{my_string}'

Проверьте ссылку: https://docs.python.org/3/library/functions.html#repr

Ответ №4:

re.escape не выполняет двойное экранирование. Это просто выглядит так, как будто вы работаете в repl. Второй уровень экранирования вызван выводом на экран.

При использовании repl попробуйте использовать print , чтобы увидеть, что на самом деле находится в строке.

 $ python
>>> import re
>>> re.escape("^stack.*/overflo\w$arr=1")
'\\\^stack\\\.\\\*\/overflo\\w\\\$arr\=1'
>>> print re.escape("^stack.*/overflo\w$arr=1")
\^stack\.\*/overflo\w\$arr=1
>>>
 

Ответ №5:

Простое использование re.sub также может работать вместо str.maketrans . И это также будет работать в python 2.x

 >>> print(re.sub(r'(-|]|^|$|*|.|\)',lambda m:{'-':'-',']':']','\':'\\','^':'^','


Ответ №6:

Используйте выходные данные встроенного repr для обработки rnt и обработки выходных re.escape данных - это то, что вы хотите:

 re.escape(repr(a)[1:-1]).replace('\\', '\')
 

:'

Ответ №6:

Используйте выходные данные встроенного repr для обработки rnt и обработки выходных re.escape данных - это то, что вы хотите:


,'*':'*','.':'.'}[m.group()],"^stack.*/overflow$arr=1"))
^stack.*/overflo\w$arr=1

Ответ №6:

Используйте выходные данные встроенного repr для обработки rnt и обработки выходных re.escape данных — это то, что вы хотите: