Правильный способ справиться с тем, что вы пытаетесь сделать, - использовать группы захвата. Это позволит вам вернуться к вашему матчу. Во-первых, позвольте мне начать с объяснения, почему ваша попытка давала вам результат, который вы видели.
Почему вы видели, что вы видели
В функции re.sub
, когда вы даете ему ' '+str(pattern)+' '
в качестве третьего параметра, это получает оценку в строку " <_sre.SRE_Pattern object at some_memory_location> "
, поскольку str(pattern)
возвращает строковое представление объекта шаблона, а не модель.
Как в сторону, на Python 3.4 и 3.5, str(pattern)
возвращает re.compile('[%&\\(\\)\\+,-./:;=–‘’“”″]')
для меня, какую версию Python вы используете? Возможно, это версия Python 2?
Решение
Как я упоминал ранее, ваше решение требует использования захвата groups. Чтобы обозначить группу, вы просто используете круглые скобки. В вашем случае, решение достаточно просто потому, что вам нужно всего лишь одну группа:
>>> import re
>>> pattern = re.compile(r"([%&\(\)\+,-./:;=–‘’“”″]+)")
Обратите внимание на мой строковый литерал, я использовал r
до начала строки. Это обозначает необработанную строку, которая заставляет строку игнорировать любую escape-последовательность , как определено Python. Например, escape-последовательность представляет собой, например, '\t'
, которая обозначает вкладку. Однако, если вы используете r'\t'
, то это фактическая строка \t
.
>>> text = "hi. hi.. hi; hi;; 55% good& good&&"
>>> pattern.sub(r' \1 ', text)
'hi . hi .. hi ; hi ;; 55 % good & good && '
Примечание я просто использовал метод sub
объекта шаблона, а не функции уровня модуля re.sub
. Это неважно, но мне кажется, что это чище. Кроме того, для аргумента замены я использовал r' \1 '
. Этот \1
относится к первой группе , снятой вашим шаблоном. Если у вас было более одной группы, вы могли бы использовать что-то вроде \2 \1
, если вы хотите, например, отменить какой-либо шаблон. Это снова, это escape-последовательность!
Потенциальное улучшение
Было неясно, в спецификации, как вы хотели бы иметь дело с более чем 2 характера, например, три символа. Таким образом, ваша модель будет иметь дело с этой ситуацией Thusly:
>>> text2 = "hi. hi.. hi; hi;; 55% good& good&& hi &&& hello,"
>>> pattern.sub(r' \1 ', text2)
'hi . hi .. hi ; hi ;; 55 % good & good && hi &&& hello , '
Возможно, это то, что вы что, но, может быть, вы хотите, чтобы рассмотреть «& & &» в виде двух отдельных матчей: «& &» и «&». Вы можете иметь дело с этой ситуацией с помощью кванторов:
>>> pattern2 = re.compile(r'([%&\(\)\+,-./:;=–‘’“”″]{1,2})')
>>> pattern2.sub(r' \1 ', text2)
'hi . hi .. hi ; hi ;; 55 % good & good && hi && & hello , '
Вместо того, чтобы использовать +
знак, который обозначает один или более-, вы можете использовать кронштейн обозначения, чтобы иметь более точный контроль. Например, {1,3} будет соответствовать от 1 до 3. {3} будет соответствовать точно 3. {3,} будет соответствовать 3 или более.
Большое вам спасибо за помощь. Я не думал, что это было так просто решить мою проблему, как вы адекватно объяснили. Что касается версии Python, я пытался ее реализовать на 3.3.2. Сейчас я установлю 3,4. Что касается раздела улучшения, я хотел иметь дело с одним или несколькими, даже тремя символами того же типа, которые должны рассматриваться как одно совпадение, и это то, что вы продемонстрировали. Еще раз спасибо за вашу помощь. – Mohammed
Однако я хочу понять использование '.sub (r '\ l', ...)'. – Mohammed
@Mohammed Ah! Да, это просто относится к первой группе, захваченной вашим шаблоном! Если у вас было несколько групп, вы могли бы ссылаться на третье как на нечто вроде 'Это третья группа: \ 3'. См. Мое редактирование. –