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.maketrans4. 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
данных — это то, что вы хотите: