tags:

views:

89

answers:

6

Hello everyone, I have been trying to teach myself Regexes in python and I decided to print out all the sentences of a text. I have been tinkering with the regular expressions for the past 3 hours to no avail.

I just tried the following but couldn't do anything.

p = open('anan.txt')
process = p.read()
regexMatch = re.findall('^[A-Z].+\s+[.!?]$',process,re.I)
print regexMatch
p.close()

My input file is like this:

OMG is this a question ! Is this a sentence ? My.
name is.

This prints no outputs. But when I remove "My. name is.", it prints OMG is this a question and Is this a sentence together as if it only reads the first line.

What is the best solution of regex that can find all sentences in a text file - regardless if the sentence carries to new line or so - and also reads the entire text? Thanks.

A: 

I tried on Notepad++, and I got this :

.*$

And activate the multiline option :

re.MULTILINE

Cheers

Ars
A: 

Try the other way around: Split the text at sentence boundaries.

lines = re.split(r'\s*[!?.]\s*', text)

If that doesn't work, add a \ before the ..

Aaron Digulla
A: 

Something like this works:

## pattern: Upercase, then anything that is not in (.!?), then one of them
>>> pat = re.compile(r'([A-Z][^\.!?]*[\.!?])', re.M)
>>> pat.findall('OMG is this a question ! Is this a sentence ? My. name is.')
['OMG is this a question !', 'Is this a sentence ?', 'My.']

Notice how name is. is not in the result because it does not start with a uppercase letter.

Your problem comes from the use of the ^$ anchors, they work on the whole text.

THC4k
Thanks a lot. I adapted it to re.findall since I have to process the txt file. Is there a way to prevent '\n' character from coming up in the result ? I mean, in sentences that carry over to new line, that \n comes up between the words in different lines.
sarevok
@sarevok: You can remove the \n before splitting it with `text.replace('\n', '')`.
THC4k
@THC4k: Thanks once again :)
sarevok
+1  A: 

There are two issues in your regex:

  1. Your expression is anchored by ^ and $, which are the "start of line" and "end of line" anchors, respectively. That means that your pattern is looking to match an entire line of your text.
  2. You are searching for \s+ before your punctuation character, which specifies one or more whitespace character. If you don't have whitespace before your punctuation, the expression will not match.
Daniel Vandersluis
Upvoted for actually explaining both things that were problems, and not just handing out a fixed regex.
cincodenada
A: 

Edited: now it will work with multiline sentences too.

>>> t = "OMG is this a question ! Is this a sentence ? My\n name is."
>>> re.findall("[A-Z].*?[\.!?]", t, re.MULTILINE | re.DOTALL )
['OMG is this a question !', 'Is this a sentence ?', 'My\n name is.']

Only one thing left to explain - re.DOTALL makes . match newline as described here

cji
A: 

You can try:

p = open('a')
process = p.read()
print process
regexMatch = re.findall('[^.!?]+[.!?]',process)
print regexMatch
p.close()

The regex used here is [^.!?]+[.!?] which tries to match one or more non-sentence delimiter followed by a sentence delimiter.

codaddict