Python заменяет все вхождения, найденные с помощью регулярных выражений

#python #regex

#python #регулярное выражение

Вопрос:

В python попытка заменить все вхождения строки, найденной с помощью регулярных выражений, таких как:

 '10am 11pm 13am 14pm 4am'
  

становится

 '10 am 11 pm 13 am 14 pm 4 am'
  

Я пытался

 re.sub('([0-9].*)am(.*)', r'1 am 2', ddata) 
  

Но это заменяет только последнее вхождение.

и

 import re
regex = re.compile('([0-9].*)am ', re.S)
myfile =  '10am 11pm 13am 14pm 4am'
myfile2 = regex.sub(lambda m: m.group().replace(r'am',r" am ",1), myfile)
print(myfile2)
  

заменяет только первое вхождение ‘am’

Ожидаемые результаты для меня '10 am 11pm 13 am 14pm 4 am'

Комментарии:

1. (d{1,2})(?=[ap]m) заменить на 1 (см. Здесь) или (d{1,2})([ap]m) заменить на 1 2 (см. Здесь)

2. Я думаю, что мне было неясно, когда я использовал reg ex в этом случае. Представьте себе предложение: «амфитеатр открывается с 10 утра до 11 утра и с 15:00 до 19:00» — мы хотим убедиться, что НЕ заменяем «am» в amphitheater.

3. Реальный вопрос в том, действительно ли вы хотите изменить это предложение / пример? Учитывая условия, которые вы установили, вы МОЖЕТЕ использовать это, но это будет некрасиво. >>> re.sub(r'(?<=d)([ap]m)', r' 1', 'the amphitheater opens at 10am-11am and 3pm-7pm') #OUTPUT: 'the amphitheater opens at 10 am-11 am and 3 pm-7 pm'

4. @FailSafe пришел к тому же выводу. положительный взгляд назад работает, но предложение выглядит уродливо. хочет ли OP что-то вроде 10 am - 11 am and 3 pm - 7 pm ? теперь это совсем другой вопрос из исходного сообщения. 🙂

5. @FailSafe это преобразование предложения НЕ предназначено для потребления человеком, так что да, я действительно хочу это сделать.

Ответ №1:

Используйте группы захвата как для цифр, так и для строки «am» или «pm», а затем просто замените пробелом между группами.

 import re

s = '10am 11pm 13am 14pm 4am'

subbed = re.sub(r'(d )([ap]m)', r'1 2', s)
print(subbed)
# 10 am 11 pm 13 am 14 pm 4 am
  

Ответ №2:

Это сделает работу:

 import re
myfile =  '10am 11pm 13am 14pm 4am'
re.sub(r'(d )(am|pm)', r'1 2', myfile)
  

Вот результат теста:

 >>> import re
>>> myfile =  '10am 11pm 13am 14pm 4am'
>>> re.sub(r'(d )(am|pm)', r'1 2', myfile)
'10 am 11 pm 13 am 14 pm 4 am'
>>> 
  

РЕДАКТИРОВАТЬ: вот результат того же решения, относящегося к строке, которую вы опубликовали в комментариях:

 >>> import re
>>> myfile = 'The amphitheater opens at 10am-11am and 3pm-7pm'
>>> re.sub(r'(d )(am|pm)', r'1 2', myfile)
'The amphitheater opens at 10 am-11 am and 3 pm-7 pm'
>>> 
  

Комментарии:

1. Я думаю, что мне было неясно, что в этом случае я использовал reg ex. Представьте себе предложение: «амфитеатр открывается с 10 до 11 утра и с 3 до 7 вечера» — мы хотим убедиться, что НЕ заменяем ‘am’ в amphitheater.

2. @jvence, вы проверили мой ответ? Он решает это без каких-либо проблем, поскольку я сопоставляю числа, за которыми следуют am или pm, без пробелов.

Ответ №3:

Если вам действительно нужно решение с использованием регулярных выражений вместо простого строкового replace метода, как упоминалось выше, вы можете использовать приведенный ниже фрагмент.

 import re
myfile = '10am 11pm 13am 14pm 4am'
myfile2 = re.sub(r'(d )(am)', lambda m: '{} {}'.format(*m.groups()), myfile, 0)
print(myfile2)
  

Комментарии:

1. Зачем вводить lambda и str.format когда вы уже используете re.sub ?

2. @accdias это необходимо, поскольку вам нужно знать цифру и информацию am / pm. Это решение является гибким для обработки информации как am, так и pm. В моем первоначальном фрагменте была вторая часть регулярного выражения as (am|pm) , которая позже была отредактирована, чтобы включать только am то, что запрашивал OP. Надеюсь, это ответит на ваш вопрос.

3. Я вижу, что вы имеете в виду здесь, вместо лямбда, вы можете напрямую использовать обратные ссылки, такие как r'1 2'

Ответ №4:

Вы могли бы сделать это без использования re:

 '10am 11pm 13am 14pm 4am'.replace('a',' a').replace('p',' p')  

## Output: '10 am 11 pm 13 am 14 pm 4 am'
  

Комментарии:

1.Благодарим вас за то, что вы не используете решение, которое сложнее, чем необходимо. Ненавижу говорить, что мне интересно, получит ли этот вопрос -1’ed? В любом случае, я опубликую это под вашим, если он захочет регулярное выражение, потому что полный ответ здесь вообще не нужен. >>> re.sub(r'(a|p)', r' 1', '10am 11pm 13am 14pm 4am') ……………. #OUTPUT: '10 am 11 pm 13 am 14 pm 4 am'

2. @FailSafe Спасибо, и ваш шаблон регулярных выражений является наиболее кратким и подходящим среди других на этой странице. Надеюсь, OP обратит на это внимание.

3. @FailSafe Смотрите комментарий, добавленный выше к предложению: «амфитеатр открывается с 10 утра до 11 утра и с 3 вечера до 7 вечера»

4. Это будет иметь побочные эффекты со строками из этого шаблона.