Как удалить дубликаты подстрок - PullRequest
2 голосов
/ 02 марта 2020

У меня есть часть строки, которая дублирует себя, и я хочу удалить все повторяющиеся «подстроки», не теряя порядок слов в строке.

Например: "12 PL DE LA HALLE BP 425 BRIVE-LA-GAILLARDE BP 425 BRIVE-LA-GAILLARDE BP 425 BRIVE-LA-GAILLARDE BP 425 BRIVE-LA-GAILLARDE"

Здесь "BP 425 BRIVE-LA-GAILLARDE" повторяется 4 раза.

Я бы хотел, чтобы строка наконец была "12 PL DE LA HALLE BP 425 BRIVE-LA-GAILLARDE", где были удалены дубликаты.

Эта проблема возникает, когда один из моих обобщенные c модули скребка собирают все текстовые элементы с определенного элемента HTML. В элементе HTML одна и та же информация повторяется несколько раз, но скрывается с помощью CSS. Вот почему я ищу универсальный способ дедупликации подстрок c.

Дополнительные примеры дублированных подстрок:

 "TOUR SOCIETE SUISSE 1 BD VIVIER MERLE 1 BD VIVIER MERLE"
      => "TOUR SOCIETE SUISSE  1 BD VIVIER MERLE"

 "2 PARC DES ERABLES 66 RTE DE SARTROUVILLE 66 RTE DE SARTROUVILLE"
      => "2 PARC DES ERABLES  66 RTE DE SARTROUVILLE"

 "CASERNE AUDEOUD 111 AV DE LA CORSE 111 AV DE LA CORSE"
      => "CASERNE AUDEOUD  111 AV DE LA CORSE"

Простой способ не повторять одно и то же слово дважды здесь не работает, потому что в случае, когда слова повторяются, но не дублируются, например: "12 PL DE LA HALLE BP 425 BRIVE LA GAILLARDE BP 425 BRIVE LA GAILLARDE", здесь "LA" между BRIVE и GAILLARDE будет удалено.

и вывод будет: "12 PL DE LA HALLE BP 425 BRIVE GAILLARDE", тогда как фактический желаемый результат: "12 PL DE LA HALLE BP 425 BRIVE LA GAILLARDE"

Я догадываюсь, что нужно сравнить последовательность слов. Но не уверен, как именно.

Любая помощь приветствуется.

Ответы [ 2 ]

2 голосов
/ 02 марта 2020

Вот потенциально жизнеспособное решение на основе регулярных выражений:

inp = "12 PL DE LA HALLE  BP 425 BRIVE-LA-GAILLARDE  BP 425 BRIVE-LA-GAILLARDE  BP 425 BRIVE-LA-GAILLARDE  BP 425 BRIVE-LA-GAILLARDE"
while True:
    out = re.sub(r'(?<!\S)(\S+(?:\s\S+)*)\s+\1(?!\S)', '\\1', inp)
    if out == inp:
        break
    inp = out
print(out)

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

12 PL DE LA HALLE  BP 425 BRIVE-LA-GAILLARDE

Идея состоит в том, чтобы соответствовать любой фразе, за которой следует та же фраза, и затем заменить только первой захваченной фразой.

Мы используем здесь рекурсивный re.sub, поскольку после обработки PHRASE PHRASE и замены всего одним PHRASE эта оставшаяся фраза не будет используется снова.

Вот объяснение шаблона регулярного выражения:

(?<!\S)         assert what precedes is either whitespace or the start of the string
(               match AND capture the following in \1
    \S+         match one or more non whitespace characters (i.e. a "word")
    (?:\s\S+)*  then match a space followed by another word, zero or more times
)
\s+             match one or more whitespace characters
\1              then match the same phrase we just saw         
(?!\S)          assert that whitespace or the end of the string follows
0 голосов
/ 02 марта 2020

Пожалуйста, проверьте это.

str = "2 PARC DES ERABLES  66 RTE DE SARTROUVILLE  66 RTE DE SARTROUVILLE"

output_str = ""
output_list =[]
for sub_str in str.split():
    if sub_str not in output_list:
        output_list.append(sub_str)
        output_str = output_str + " " + sub_str

print(output_str.strip())

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...