2016-12-03 2 views
1

Я определилнеожиданное поведение re.sub

s='f(x) has an occ of x but no y' 
def italicize_math(line): 
    p="(\W|^)(x|y|z|f|g|h)(\W|$)" 
    repl=r"\1<i>\2</i>\3" 
    return re.sub(p,repl,line) 

и сделал следующий вызов:

print(italicize_math(s) 

Результат является

'<i>f</i>(x) has an occ of <i>x</i> but no <i>y</i>' 

, который не то, что я ожидал. Я хотел вместо этого:

'<i>f</i>(<i>x</i>) has an occ of <i>x</i> but no <i>y</i>' 

Может кто-нибудь сказать мне, почему первое вхождение й не было заключено в внутри «Я» тегов?

+0

Решения, которые я получил, было довольно хорошо, но теперь я понимаю, что нужно что-то более мощное, как словоразделы в обеспечиваемой \ Ь не являюсь ограничительными достаточно. Я бы хотел, чтобы 4x было преобразовано в 4 x. Другими словами, наличие 4 рядом с x должно быть границей. Я посмотрю на обычные утверждения. – user1741137

+0

Благодаря приведенным ниже выводам я обнаружил, что p = '(? \ 1 «соответствует моим потребностям – user1741137

ответ

4

Вы, кажется, пытается соответствовать не буквенно-цифровые символы (\W), когда вы действительно хотите границу слова (\b):

>>> p=r"(\b)(x|y|z|f|g|h)(\b)" 
>>> re.sub(p,repl,s) 
'<i>f</i>(<i>x</i>) has an occ of <i>x</i> but no <i>y</i>' 

Конечно, (является не алфавитно-цифровой - The причина, по которой ваш внутренний контент не соответствует, заключается в том, что \W потребляет персонажа в матче. поэтому со строкой, как 'f(x)', вы соответствуете (, когда вы соглашаетесь f. С ( был уже выбран, но он не будет соответствовать при попытке соответствовать x. Напротив, границы слов не потребляют никаких символов.

3

Поскольку групповая конструкция сопоставляет позицию в начале строки сначала, а x будет перекрывать предыдущее совпадение. Кроме того, первая и третья группы являются избыточными, поскольку их можно заменить границами слов; и вы можете использовать класс символов для объединения букв.

p = r'\b([fghxyz])\b' 
repl = r'<i>\1</i>' 
1

Как и предыдущие упоминания ответа, потому что его ( гольца существо потреблять при совпадении f таким образом вызвать последующее x провалить матч.

Помимо замены на границу слова \b, вы также можете использовать регулярное выражение lookahead, которое просто заглядывает и не будет потреблять ничего похожего на внешний вид. Поскольку ничего не потреблять, вы не нужны \3 либо

p=r"(\W|^)(x|y|z|f|g|h)(?=\W|$)" 
repl=r"\1<i>\2</i>" 
re.sub(p,repl,line) 
Смежные вопросы