Предложение совпадает с регулярным выражением

У меня есть текст, который разбивается на множество строк, без каких-либо конкретных форматов. Поэтому я решил line.strip('\n') для каждой строки. Затем я хочу разделить текст на предложения, используя маркер конца предложения . принимая во внимание:

  1. период . за которым следует \s (Пробел), \S (лайк "') и затем [A-Z] разделится
  2. не разделять [0-9]\.[A-Za-z], лайк 1.stackru real time solution,

Моя программа решает только половину 1 - периода (.), За которым следуют \s и [AZ]. Ниже приведен код:

# -*- coding: utf-8 -*-
import re, sys

source = open(sys.argv[1], 'rb')
dest = open(sys.argv[2], 'wb')
sent = []
for line in source:
    line1 = line.strip('\n')
    k = re.sub(r'\.\s+([A-Z“])'.decode('utf8'), '.\n\g<1>', line1)
    sent.append(k)

for line in sent:
    dest.write(''.join(line))

Pls! Я хотел бы знать, что является лучшим способом освоить регулярные выражения. Кажется, это сбивает с толку.

1 ответ

Решение

Чтобы включить одинарную кавычку в класс символов, используйте клавишу \. Регулярное выражение должно быть:

\.\s+[A-Z"\']

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

Это регулярное выражение будет соответствовать любому периоду, за которым следует пробел, за которым следует заглавная буква или цитата. Поскольку период, которому непосредственно предшествует число и сразу за которым следует буква, не соответствует этим критериям, он не будет совпадать.

Это предполагает, что регулярное выражение, с которым вы работали, разделяло период, за которым следовали пробелы и прописные буквы, как вы заявили. Обратите внимание, однако, что это означает, что I am Sam. Sam I am. разделится на I am Sam а также am I am, Это действительно то, что вы хотите? Если нет, используйте утверждения нулевой ширины, чтобы исключить части, которые вы хотите сопоставить, но также сохранить. Вот ваши варианты, в порядке того, что я думаю, скорее всего, вы хотите.

1) Сохраните точку и первую букву или вступительную цитату следующего предложения; потерять пробел:

(?<=\.)\s+(?=[A-Z"\'])

Это разделит пример выше на I am Sam. а также Sam I am.

2) сохранить первую букву следующего предложения; потерять период и пробелы:

\.\s+(?=[A-Z"\'])

Это разделится на I am Sam а также Sam I am, Это предполагает, что после этого будет больше предложений, в противном случае период останется со вторым предложением, потому что за ним не следует пробел и заглавная буква или кавычка. Если эта опция - та, которая вам нужна - предложения без точек, тогда вы можете также захотеть сопоставить точку, за которой следует конец строки, с необязательными промежуточными пробелами, так что последний период и любые пробелы будут удалены:

\.(?:\s+(?=[A-Z"\'])|\s*$)

Обратите внимание ?:, Вам нужны неперехватывающие скобки, потому что если у вас есть группы захвата в разделении, то все, что захвачено группой, добавляется как элемент в результаты (например, split('(+)', 'a+b+c' дает вам массив a+b+c а не просто abc).

3) Держите все; Пробел идет с предыдущим предложением:

(?<=\.\s+)(?=[A-Z"\'])

Это даст вам I am Sam. а также Sam I am.

Что касается последней части вашего вопроса, лучший ресурс по синтаксису регулярных выражений, который я видел, это http://www.regular-expressions.info/. Начните с этой сводки: http://www.regular-expressions.info/reference.html Затем перейдите на страницу "Учебное пособие" для получения более подробной информации: http://www.regular-expressions.info/tutorial.html

Другие вопросы по тегам