Python находит все вхождения переносимого слова и заменяет в позиции - PullRequest
2 голосов
/ 04 июня 2019

Я должен заменить все вхождения шаблонов дефисом, например c-c-c-c-come или oh-oh-oh-oh и т. Д., Последним токеном, например, come или oh в этом примере, где

  • Число символов между дефисами является произвольным, оно может быть на один или более символов
  • маркер для сопоставления является последним токеном в переносе, следовательно, come в c-c-come.
  • входная строка может иметь одно или несколько вхождений, например, следующие предложения:

    c-c-c-c-come to home today c-c-c-c-come to me

    oh-oh-oh-oh it's a bad life oh-oh-oh-oh

  • Необходимонайти начальную и конечную позиции сопоставленного токена с помощью finditer

    r = re.compile(pattern, flags=re.I | re.X | re.UNICODE)
    for m in r.finditer(text):
       word=m.group()
       characterOffsetBegin=m.start()
       characterOffsetEnd=m.end()
       # now replace and store indexes
    

[ОБНОВЛЕНИЕ]

Предполагается, что эти переносимые словане принадлежит к фиксированному словарю, я добавляю к нему следующее ограничение:

  • Число символов между дефисами должно варьироваться от минимального до максимального, например {1,3}, так что группа захвата должнасоответствует c-come или c-c-come, но не реальное слово, такое как fine-tuning или inter-face и т. д.

Ответы [ 4 ]

4 голосов
/ 04 июня 2019

Вы можете просто использовать re.sub(), чтобы заменить все без перебора соответствующих индексов:

import re

s = 'c-c-c-c-come to home today c-c-c-c-come to me'

print(re.sub(r'(\w+(?:-))+(\w+)', '\\2', s))
# come to home today come to me
1 голос
/ 04 июня 2019

Опция, использующая группу захвата и обратную ссылку, может быть:

(?<!\S)(\w{2,3})(?:-\1)*-(\w+)(?!\S)

Это будет соответствовать:

  • (?<!\S) Отрицательный вид сзади, утверждают, что слеване символ без пробела
  • (\w{2,3}) Захват в группе 1 два или три раза слово char
  • (?:-\1)* Повторите 0+ раз, сопоставляя дефис с последующей обратной ссылкой на то, что сопоставлено вгруппа 1
  • -(\w+) Совпадение -, за которым следует сопоставление символов 1+ в группе 2
  • (?!\S) Отрицательный взгляд вперед, утверждайте, что справа не является непробельным символом

При замене используйте вторую группу захвата \\2 или r'\2

Regex demo | Python demo

Например

import re

text = "c-c-c-c-come oh-oh-oh-oh it's a bad life oh-oh-oh-oh"
pattern = r"(?<!\S)(\w{1,3})(?:-\1)*-(\w+)(?!\S)"
text = re.sub(pattern, r'\2', text)
print(text)

Результат

come oh it's a bad life oh
1 голос
/ 04 июня 2019

Вот одно из возможных выражений:

import re

text = ("c-c-c-c-come to home today c-c-c-c-come to me, "
        "oh-oh-oh-oh it's a bad life oh-oh-oh-oh")
pattern = r"(?<=-)\w+(?=[^-\w])"
r = re.compile(pattern, flags=re.I | re.X | re.UNICODE)
for m in r.finditer(text):
    word = m.group()
    characterOffsetBegin = m.start()
    print(word, characterOffsetBegin)

Выход:

come 8
come 35
oh 56
0 голосов
/ 04 июня 2019

Это можно сделать без регулярных выражений. Код:

s = "c-c-c-c-come to home today c-c-c-c-come to me"
s = " ".join(w if "-" not in w else w[w.rindex('-') + 1:] for w in s.split(" "))

Выход:

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