deadrime
@deadrime
Fullstack web developer

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

Дали в вузе задачку - разбить русский текст в utf-8 на предложения. Но без регулярных выражений.
Нужно, чтобы программа обрабатывала ситуацию, когда первое слово предложения начинается с прописной буквы.
Казалось бы легко -
text = text.replace('. ', '.|').replace('! ', '!|').replace('? ', '?|')
sentences = text.split('|')

Но даётся такой текст, что
Попробуй, подойди! вишь какой! вот большая цяца! ты думаешь, я на тебя суда не найду

это одно предложение. И '! ' уже будет обрабатываться неправильно.

Ладно, думаю, можно, наверное потом пройтись по списку предложений и проверять, начинается ли следующее с маленькой буквы, если да - то объединить его с предыдущим.
т.е. что-то типа
i = 0
while i < len(sentences) - 1:
    if not sentences[i + 1].istitle():
        sentences[i] += sentences[i + 1]
        sentences.pop(i + 1)
    i += 1

Но... Этот костыль не особо работает, возможно из-за русской кодировки.

В общем что-то я не понял, пробовал сравнить с диапазоном кодов символов больших букв в юникоде, но он почему-то ругается на
ch1 = 'Б'
print ord(ch1)

Говорит, мол
TypeError: ord() expected a character, but string of length 2 found


А .istitle вообще работает неправильно -

ch1 = 'Б'
ch2 = 'б'
if ch1.istitle():
    print ("Верхний")
else:
    print ("Нижний")


if ch2.istitle():
    print ("Верхний")
else:
    print ("Нижний")


Выводит нижний в обоих случаях..

Может я не в те дебри забрел и решение куда проще?

Вот такой вот текст предлагают разбить на предложения в задании:
"Смотри, как расхрабрился!" говорил Чуб, оставшись один на улице. „Попробуй, подойди! вишь какой! вот большая цяца! ты думаешь, я на тебя суда не найду. Нет, голубчик, я пойду, и пойду прямо к комиссару. Ты у меня будешь знать. Я не посмотрю, что ты кузнец и маляр. Однако ж посмотреть на спину и плечи: я думаю, синие пятна есть. Должно быть, больно поколотил вражий сын! жаль, что холодно и не хочется скидать кожуха! Постой ты, бесовской кузнец, чтоб чорт поколотил и тебя, и твою кузницу, ты у меня напляшешься! вишь, проклятый шибеник! однако ж, ведь теперь его нет дома. Солоха, думаю, сидит одна. Гм... оно ведь недалеко отсюда; пойти бы! Время теперь такое, что нас никто не застанет. Может, и того будет можно... вишь, как больно поколотил проклятый кузнец!“


Ну т.е. по сути алгоритм тут простой, нужно добавить в список все, что было до [i]-го символа, если
1)[i] == '.' and [i+1]==' ' and [i+2] - Символ верхнего регистра
2)[i] == '!' and [i+1]== ' ' and [i+2] - Символ верхнего регистра
3) Тоже самое для '?'
  • Вопрос задан
  • 534 просмотра
Решения вопроса 1
aRegius
@aRegius
Python Enthusiast
"Дожмите" ваше собственное решение
text = text.replace('. ', '.|').replace('! ', '!|').replace('? ', '?|')


добавив проверку на вхождение заглавных букв и чуточку подкорректировав аргументы в replace():
>>> letters = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ'
>>> text = '"Смотри, как расхрабрился!" говорил Чуб, оставшись один на улице..' # и далее по тексту
>>> for letter in letters:
	        if letter in text:
		            text = text.replace('. '+letter, '.|'+letter).replace('. "'+letter, '.|"'+letter).replace('! '+letter, '!|'+letter)
		
>>> for sentence in text.split('|'):
	        print(sentence)
	
"Смотри, как расхрабрился!" говорил Чуб, оставшись один на улице.
"Попробуй, подойди! вишь какой! вот большая цяца! ты думаешь, я на тебя суда не найду.
Нет, голубчик, я пойду, и пойду прямо к комиссару.
Ты у меня будешь знать.
.... 
и т.д.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@NaName
ch1 = u'Б'
ch2 = u'б'
if ch1.istitle():
    print ("Верхний")
else:
    print ("Нижний")

так пробовали?
Ответ написан
Комментировать
Winsik
@Winsik
сис.админ, недопрограммист :)
i = 0
while i < len(sentences) - 1:
    if ord(sentences[i + 1])>1039 and ord(sentences[i + 1])<1071:
      print (sentences[i + 1])
    i += 1

;) метод топором =)

p.s. Только не забудьте , у вас ещё присутствуют предложения такие: бла бла. "Ой..."
Ответ написан
Комментировать
@abcd0x00
Казалось бы легко -

Это только кажется, и дело тут не в том, как определить строчную или прописную букву. Дело в алгоритме. Это задача относится к написанию лексического анализатора, а пишутся они через конечные автоматы.
wiki. конечный автомат (пример)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы