Соответствие регулярного выражения на нескольких перекрывающихся вхождениях? - PullRequest
1 голос
/ 18 июня 2020

У меня есть строки, которые выглядят так:

sometext 3x 24x5 x 17.5 x 3 sometext

И я хотел бы объединить все экземпляры di git + необязательный пробел + x + необязательный пробел + di git в di git + х + ди git. Желаемый результат:

sometext 3x24x5x17.5x3 sometext

Мое текущее регулярное выражение выглядит нормально, но почему-то не работает:

re.sub(r'(\d)\s?([x])\s?(\d)', r'\1\2\3', 'sometext 3x 24x5 x 17.5 x 3 sometext')

Выход

sometext 3x24x5 x 17.5x3 sometext

Кажется, это должно делать с тем фактом, что 24x5 уже захвачено выражением, поэтому оно не учитывает 5 x 17. Мой вопрос будет, как настроить мое регулярное выражение для желаемой цели, и есть ли более чистый / эффективный способ напишите это регулярное выражение, чем мой подход? Спасибо!

Ответы [ 2 ]

2 голосов
/ 18 июня 2020

Я предлагаю два варианта:

import re
s = 'sometext 3x 24x5 x 17.5 x 3 sometext'
print (re.sub(r'(?<=\d)\s+(?=x)|(?<=x)\s+(?=\d)', '', s))
print (re.sub(r'(?<=\d)\s+(?=x\s*\d)|(\d)\s*(x)\s+(?=\d)', r'\1\2', s))

См. Python демо . Оба возвращают sometext 3x24x5x17.5x3 sometext, но второй кажется более точным.

Regex # 1 подробности

  • (?<=\d)\s+(?=x) - один или несколько пробелов между di git и x
  • | - или
  • (?<=x)\s+(?=\d) - один или несколько пробелов между x и di git

Regex # 2 подробности

  • (?<=\d)\s+(?=x\s*\d) - один или несколько пробелов между di git и x + ноль или более пробелов и di git
  • | - или
  • (\d)\s*(x)\s+(?=\d) - соответствует di git (захвачено в Группу 1), затем один или больше пробелов, затем x (захвачено в группе 2), а затем \s+ соответствует 1 или более пробелам, за которыми следует di git.

Замена - это объединение групп 1 и 2 значения.

2 голосов
/ 18 июня 2020

Вы можете использовать re.sub для идентификации всех терминов с числом x, а затем использовать обратный вызов для удаления всех пробелов из каждого совпадения:

inp = "sometext 3x 24x5 x 17.5 x 3 sometext 1 x 2.3 x 4"
output = re.sub(r'\d+(?:\.\d+)?(?:\s*x\s*\d+(?:\.\d+)?)+', lambda m: re.sub(r'\s', '', m.group(0)), inp)
print(output)

Это напечатает:

sometext 3x24x5x17.5x3 sometext 1x2.3x4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...