The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> Python Programming
|
Re.findall help
Discuss Re.findall help in the Python Programming forum on Dev Shed. Re.findall help Python Programming forum discussing coding techniques, tips and tricks, and Zope related information. Python was designed from the ground up to be a completely object-oriented programming language.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

January 26th, 2013, 06:16 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 27
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
|
|
|
Re.findall help
Hi, so I'm fairly new to python but I've been practicing coding on my own.
Recently, I'm working with the re.match, re.findall, re.ignorecase.
This is my code:
Code:
def mission(s):
match = re.findall(r'\d+', s, re.IGNORECASE)
return match
It gives me this output:
Code:
['1', '0']
['20', '500']
['3']
['20', '1']
From this:
Code:
mission('Recon Mission 1 accomplished. Enemy found: 0.')
mission('recon mission 20 accomplished. enemies found: 500.')
mission("Recon Mission 3 failed.")
mission("I have 20 carrots and 1 mushroom.")
But I need to get this output:
Code:
(1, 0)
(20, 500)
(3, failed)
fourth line returns empty b/c it does not contain mission or status
I'm not sure how to extract mission number and status (either 'failed' or number of enemies found)
Any suggestions on how to do this correctly?
|

January 26th, 2013, 07:27 PM
|
 |
Contributing User
|
|
|
|
1) convert the number strings to integers.
2) Use simple regular expressions. Don't try to parse English with a single re.
This code might be closer to what you want. Could be more restrictive about accepting interesting sentences.
Code:
# python -m doctest -v p.py
import re
def mission(s):
'''
>>> (1, 0) == mission('Recon Mission 1 accomplished. Enemy found: 0.')
True
>>> (20, 500) == mission('recon mission 20 accomplished. enemies found: 500.')
True
>>> (3, 'failed') == mission("Recon Mission 3 failed.")
True
>>> () == mission("I have 20 carrots and 1 mushroom.")
True
'''
match = list(map(int,re.findall(r'\d+', s)))
sl = s.lower()
if 'mission' in sl:
if ('accomplished' in sl) and ('found' in sl):
return tuple(match)
if match and ('failed' in sl):
return (match[0],'failed',)
return ()
__________________
[code] Code tags[/code] are essential for python code!
|

January 26th, 2013, 07:56 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 27
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
|
|
Thanks for that @b49P23TIvg
what does map() do?
But while I was away, I actually figured out how to do it another way, the only problem I have now is how to remove the brackets and quotation marks from the numbers to just have parentheses.
This is my code now:
Code:
def mission(s):
first = re.findall(r'Recon Mission (\d+)', s, re.IGNORECASE)
second = re.findall(r'found: (\d+)', s)
if first and second:
s = first, second
elif first and second !=None:
second = 'failed'
s = first, second
else:
s = None
return s
My output:
Code:
(['1'], ['0'])
(['2'], ['500'])
(['3'], 'failed')
None
How to code to get my (['1'], ['0']) to output as (1, 0)?
Or is it not possible to do so unless I do it your way or another way?
|

January 26th, 2013, 08:43 PM
|
 |
Contributing User
|
|
|
|
Using your mission function, we can clean the output into strings matching your requirement.
Code:
import re
def mission(s):
first = re.findall(r'Recon Mission (\d+)', s, re.IGNORECASE)
second = re.findall(r'found: (\d+)', s)
if first and second:
s = first, second
elif first and second !=None:
second = 'failed'
s = first, second
else:
s = None
return s
def clean(s):
'''
>>> print(clean(mission('Recon Mission 1 accomplished. Enemy found: 0.')))
(1, 0)
>>> print(clean(mission('recon mission 20 accomplished. enemies found: 500.')))
(20, 500)
>>> print(clean(mission("Recon Mission 3 failed.")))
(3, failed)
>>> print(clean(mission("I have 20 carrots and 1 mushroom.")))
None
'''
return re.sub("[][']",'',str(s)) # as a regular expression
return str(s).replace('[','').replace(']','').replace("'",'') # with builtin string methods
map(function,iterable)
Suppose function(object_x) returns object_y .
Then if iterating iterable gives objects_x
map(function,objects_x)
is an iterable that, when iterated gives objects_y . I've stated this confusingly, obtusely, but generally. map changed between python 2 and 3. In python 3 map uses lazy evaluation, it avoids calling the function until the result is needed. map isn't so hard.
For example, in python 2 and 3
Code:
>>> def double(a): return 2*a
...
>>> list(map(double,[3,'ho']))
[6, 'hoho']
>>>
|

January 26th, 2013, 09:07 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 27
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
|
|
thank you, I understand the map function now
Also, thanks for the other code, I've implemented it and although it removed the brackets and double quotes, it still seems to have the single quotes, at least it's replaced it all with the single quote.
My output is closer to what I want but instead of (1,0) I now get '(1,0)'
Is there a way to get rid of ' around the parentheses? Or is there a way to replace ' with an empty str?
thank you again!
|

January 26th, 2013, 09:21 PM
|
 |
Contributing User
|
|
|
|
|
>>> print( 'string' )
string
>>> 'string'
'string'
>>>
|

January 26th, 2013, 09:37 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 27
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
|
|
Hmm...I understand the print ('string') but I think it's different from what I actually want b/c that's the word itself: string
I'm not sure that it will work in my situation...sry if I'm a bit slow and not really explaining myself well...
I guess I'll continue to play around with the code and google some more.
this is my code now:
Code:
def mission(s):
first = re.findall(r'Recon Mission (\d+)', s, re.IGNORECASE)
second = re.findall(r'found: (\d+)', s)
if first and second:
s = first, second
x = str(s).replace('[','').replace(']','').replace("'",'')
elif first and second !=None:
second = 'failed'
t = first, second
x = str(t).replace('[','').replace(']','').replace("'",'')
else:
x = None
return x
My output:
Code:
'(1, 0)'
'(2, 500)'
'(3, failed)'
None
I think I'm suppose to use int() but when I tried implementing that, it didn't really work, I kept getting an error.
|

January 26th, 2013, 09:48 PM
|
 |
Contributing User
|
|
|
|
|
We've come full circle, using integers then removing characters from strings to make them look like numbers.
If you truly want
(3, failed)
then it's a string, not a number and a piece that doesn't look like a number or a string.
|

January 26th, 2013, 10:08 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 27
Time spent in forums: 17 h 19 m 39 sec
Reputation Power: 0
|
|
yeah, I feel like I'm making things worse and confusing myself more. Sry about that.
I went back and decided to just implement your earlier code so now I have this:
Code:
def mission(s):
match = map(int,re.findall(r'\d+', s))
sl = s.lower()
if 'mission' in sl:
if ('accomplished' in sl) and ('found' in sl):
s = tuple(match)
if match and ('failed' in sl):
s = (match[0],'failed',)
else:
s = None
return s
It works the way I want it to now so thank you.
Just one last question, if I wanted to implement re.Ignorecase instead of using s.lower(), how would I go about doing that?
|

January 27th, 2013, 12:47 PM
|
 |
Contributing User
|
|
|
|
I removed Ignorecase because it had nothing to do with digits. Maybe with these.
Code:
if re.search('mission',s,re.Ignorecase):
if re.search('accomplished.*found',s,re.Ignorecase):
if match and (re.search('failed',s,re.Ignorecase)):
untested.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|