Как написать регулярное выражение, чтобы исправить слова, состоящие из повторяющихся букв?

#python #regex

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

Вопрос:

Я очистил несколько PDF-файлов, и некоторые толстые шрифты были удалены, как в этом примере:

 text='and assesses oouurr rreeffoorrmmeedd tteeaacchhiinngg in the classroom'
  

вместо

 "and assesses our reformed teaching in the classroom"
  

Как это исправить? Я пытаюсь использовать регулярное выражение

 pattern=r'([a-z])(?=1)'
re.sub(pattern,'',text)
#"and aseses reformed teaching in the clasrom"
  

Я подумываю о группировании двух групп выше и добавлении границ слов

РЕДАКТИРОВАТЬ: это исправляет слова с четным количеством букв:

 pattern=r'([a-z])1([a-z])2'
re.sub(pattern,'12',text)
#"and assesses oouurr reformed teaching in the classroom"
  

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

1. Для этого потребуется некоторая библиотека NLP, потому что вы не можете просто удалить все повторяющиеся буквы

2. Одно только регулярное выражение не может понять, что rreeffoorrmmeedd должно быть сведено к reform , но assesses не должно сводиться к aseses . Здесь вам нужен какой-то словарь.

3. Каков ваш идеальный результат (какой уровень неточности допустим?)

4. @Nick Это не обязательно должно быть идеальным, но оно не должно портить хорошие слова. Чем больше слов я исправлю, тем лучше. В любом случае я запущу NLP и удалю все неправильные слова.

Ответ №1:

Если буквы дублируются, вы можете попробовать что-то вроде этого

 for w in text.split():
    if len(w) %2 != 0:
        print(w)
        continue
    if w[0::2] == w[1::2]:
        print(w[0::2])
        continue
    print(w)
  

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

1. приятно! что, если строка содержит разделители, отличные от пробела, такие как n ?

2. split разделителем по умолчанию является любой пробел

Ответ №2:

Я использую смешанный подход: создаю шаблон и подстановку в цикле for, затем применяю регулярное выражение. Применяемые регулярные выражения варьируются, например, от слов из 8×2 = 16 букв до 3.

 import re
text = 'and assesses oouurr rreeffoorrmmeedd tteeaacchhiinngg in the classroom'
wrd_len = [9,8,7,6,5,4,3,2]
for l in wrd_len:
    sub = '\'   '\'.join(map(str,range(1,l 1)))
    pattern = '([a-z])\'   '([a-z])\'.join(map(str,range(1,l 1)))
    text = re.sub(pattern, sub , text)
text
#and assesses our reformed teaching in the classroom
  

Например, регулярное выражение для 3-буквенных слов становится:

 re.sub('([a-z])1([a-z])2([a-z])3', '123', text)
  

В качестве примечания, я не смог правильно использовать эти обратные косые черты с необработанными строками, и я на самом деле собираюсь использовать [a-zA-Z] .

Ответ №3:

я нашел решение в javascript, которое отлично работает :

 ([a-z])1(?:(?=([a-z])2)|(?<=3([a-z])11))
  

но в некоторых случаях это не работает в python, потому что lookbehind не может принимать ссылки на group, поэтому я придумал другое решение, которое может работать в этом примере :

 ([a-z])1(?:(?=([a-z])2)|(?=[^a-z])))
  

попробуйте это здесь