Дополнительная точка в регулярном выражении
Скажем, я хочу заменить все совпадения Mr.
и Mr
на Mister
.
Я использую следующее регулярное выражение: \bMr(\.)?\b
для соответствия либо Mr.
, либо просто Mr
. Затем я использую re.sub()
метод для замены.
Меня озадачивает то, что он заменяет Mr.
на Mister.
. Почему это поддерживает точку .
в конце? Похоже, что это не соответствует случаю Mr\.
, а просто Mr
.
import re
s="a rMr. Nobody Mr. Nobody is Mr Nobody and Mra Nobody."
re.sub(r"\bMr(\.)?\b","Mister", s)
Возврат:
'a rMr. Nobody Mister. Nobody is Mister Nobody and Mra Nobody.'
Я также пробовал следующее: но и не повезло:
re.sub(r"\b(Mr\.|Mr)\b","Mister", s)
Мой желаемый результат:
'a rMr. Nobody Mister Nobody is Mister Nobody and Mra Nobody.'
^ ^
no dot this should be kept as it is
Ответы
Ответ 1
Я думаю, вы хотите захватить 'Mr'
, за которым следует либо '.'
, либо граница слова:
r"\bMr(?:\.|\b)"
При использовании:
>>> import re
>>> re.sub(r"\bMr(?:\.|\b)", "Mister", "a rMr. Nobody Mr. Nobody is Mr Nobody and Mra Nobody.")
'a rMr. Nobody Mister Nobody is Mister Nobody and Mra Nobody.'
Ответ 2
Я думаю, что в исходном посте \b
была причиной некоторой путаницы.
От regex101:
\ b соответствует, не потребляя никаких символов, сразу между символ, сопоставляемый символом \w и символом, не совпадающим с \w (в порядок).
и
\ w соответствует любой букве, номеру или подчеркиванию.
OP ожидал, что \b
будет соответствовать границе между точкой и пробелом, следующим за ней. Но это не так, потому что точка не соответствует \w
. Вместо этого \b
соответствует границе между текстом "Mr" и точкой. Это заставило точку не попасть в плен, о которой спрашивал ОП. Это можно увидеть здесь:
![enter image description here]()
Ответ 3
re.sub(r"\bMr\.|\bMr\b","Mister", s)
Попробуйте это. Вам нужно удалить \b
после .
Вывод: a rMr. Nobody Mister Nobody is Mister Nobody and Mra Nobody.'
Причина, по которой \bMr(\.)?\b
не работает, потому что между .
и space
нет границы слова.
В качестве границ слов существуют три разных позиции:
- Перед первым символом в строке, если первый символ является символом слова.
- После последнего символа в строке, если последний символ является символом слова.
- Между двумя символами в строке, где один является символом слова, а другой не является символом слова.
Ответ 4
>>> s="a rMr. Nobody Mr. Nobody is Mr Nobody and Mra Nobody."
>>> re.sub(r'\b(Mr[\.\s]\s*)',r'Mister ',s)
'a rMr. Nobody Mister Nobody is Mister Nobody and Mra Nobody.'
Ответ 5
re.sub(r'\bMr[\s\.]', 'Mister ', s)
Если бы это был Code Golf, я бы выиграл?
Ответ 6
@jonsharpe отвечает, но это немного проще: \bMr(\.|\b)
http://regex101.com/r/sC9nG6/2