2015-07-26 8 views
1

У меня возникла ситуация, когда я могу столкнуться с «{ключом» или «{ключ \ n», и я хочу преобразовать «{key \ n» в «{key], не затрагивая другие экземпляры« \ n »в строке , ключ может содержать любой из a-z, A-Z, 0-9, подчеркивание, тире.Python 2.6.1 (OS X 10.6.8) re.sub() поведение подчеркивания в группах?

Я думал, что это будет работать, но это не делает:

import re 
test = '{sq-a_ foo}{sq-b_\nbar}\n{sq-c_ gluck}' 
print re.sub(r'(\{*[_a-zA-Z0-9-]\n)','\1 ',test) 

возвращает это:

{sq-a_ foo}{sq-b bar} 
{sq-c_ gluck} 

... где есть невидимый персонаж, 0x01, именно там, где подчеркивание должен быть заменен.

Я ожидал это:

{sq-a_ foo}{sq-b_ bar} 
{sq-c_ gluck} 

Так что мои вопросы, где же подчеркивание после sq-b идти? Откуда у этого 0x01?

  • Подчеркивание соответствует, очевидно, так как он был заменен
  • это внутри скобок так что в группе 1
  • группа 1 является то, что вышло в замене (без подчеркивания)
+1

Как это не показано в вашем вопросе, вы признали, что недостающее подчеркивание было преобразовано в u '\ x01'? –

+0

Матиас, я не понимаю, что ты просишь или пытаешься мне сказать? Какое значение имеет порядковое значение 1? – fyngyrz

+1

Я не знаю, это просто наблюдение, что при запуске вашего кода результирующая строка содержит «\ x01» в точном месте, где вы ожидаете «_» –

ответ

1

Вы сделали две ошибки, вы захватили \n и вы забыли r в вашей подстроке:

import re 
test = '{sq-a_ foo}{sq-b_\nbar}\n{sq-c_ gluck}' 
print re.sub(r'(\{*[_a-zA-Z0-9-])\n',r'\1 ',test) 

Кроме того, в качестве @ remus, вы можете заменить a-zA-Z0-9_ на \w, чтобы вы могли упростить:

re.sub(r'(\{*[\w-])\n', r'\1 ', test) 
+0

Идеальный ответ. Краткая и правильная. Твердый, брат. :) – fyngyrz

+1

Принимая это имеет больше значения, чем комментарий, то;) –

+0

конечно. Derp – fyngyrz

1

Сначала давайте посмотрим ваше оригинальное выражение:

\{* соответствует 0 или более буквам {. В этом случае, поскольку ожидается, что следующий символ - один из этих _a-zA-Z0-9-, за которым следует \n, он фиксирует символ последнего до \n и фактически делает заявление \{* несущественным.

И после этого, так как \n включен в вашу группу захвата вместе с этим другим персонажем, когда вы заменяете его \1 backreference, новая строка включена в замену вместе с этим другим персонажем. В этом случае вы заменяете _\n пробелом, и поэтому пространство исчезает.

Это дает мне ответ, в том числе подчеркивание - если вы хотите заменить разрыв строки, вам нужно исключить его из группы захвата. Кроме того, глупо мне, я пропустил отсутствие символьной строки r'' префикса на обратной ссылке:

import re 
test = '{sq-a_ foo}{sq-b_\nbar}\n{sq-c_ gluck}' 
print re.sub(r'(\{[^}]+)\n(.+\})',r'\1 \2',test) 

Выход:

{sq-a_ foo}{sq-b_ bar} 
{sq-c_ gluck} 

Также стоит отметить - вы можете просто ваше выражение с помощью \w вместо a-zA-Z_;)

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

re.sub(r'(?!\})\n', ' ', test); 

... заменит все экземпляры новой строки, не предшествующие }. В зависимости от того, что вы пытаетесь сделать, это может быть намного проще.

Другой альтернативой является использование отрицательного просмотра назад:

re.sub(r'(?![\w-])(\n)', ' ', test); 
+0

Нет, это не нормально (или правильно) результат. Все дело в том, чтобы заменить этот разрыв строки пробелом. Результаты, которые я ожидал и нуждаются, подробно изложены в этом вопросе. Я попробовал то, что вы предлагаете, кстати, получил те же результаты, что и вы, что замена не происходит. – fyngyrz

+0

Хорошо, там вы идете. – brandonscript

+0

UH, ok nevermind Теперь я вижу скрытых персонажей. Это все дело. – brandonscript

 Смежные вопросы

  • Нет связанных вопросов^_^