-1

Here is my code:

s = '''I wish I may, I wish I might
Have a dish of fish tonight.'''

import re
m = re.search('w.*m', s)
print(m.group())

and I got the result:

wish I may, I wish I m

If I want to get the result only the first half wish I m, how can I revise my code?

Thanks a lot!

falsetru
  • 357,413
  • 63
  • 732
  • 636

3 Answers3

2

Use .*? to match non-greedily.

>>> s = '''I wish I may, I wish I might
... Have a dish of fish tonight.'''
>>> 
>>> import re
>>> m = re.search('w.*?m', s)
>>> m.group()
'wish I m'
falsetru
  • 357,413
  • 63
  • 732
  • 636
0

What are you trying to accomplish here? Your regular expression means it will match any of the following

'w.*m' will match:
'well my cat is married' -> 'well my cat is m'
'willy wonka had a wonky moped' -> 'willy wonka had a wonky m'

You are pretty much saying it should match any phrase that starts with w and ends with m.

wish i m appears twice in the phrase as highlighted below

"I wish I may, I wish I might Have a dish of fish tonight."

So if that's the phrase you are looking for, your result should be wish I m, wish I m. For that result you'd need this pattern - w[\w\s]*m. So instead of a greedy .* you are limiting the matched characters to words \w and spaces \s which is all that is in will I m.

Again, it depends on what you are looking for.

In [1]: import re
In [4]: x = 'I wish I may, I wish I might Have a dish of fish tonight'
In [5]: re.findall(r'w[\w\s]*m', x)
Out[5]: ['wish I m', 'wish I m']
Okezie
  • 5,012
  • 3
  • 26
  • 27
0

In regular expressions, . means a single character and .* means any number of characters (0 or more).

When you used w.*m, by default, python will look for the longest sub-string that starts with w and ends with m. This is called GREEDY MATCH.

To find a smaller sub-string in a string that starts with w and ends with m, you have to search NON GREEDILY.

For this, instead of using w.*m, use w.*?m . Because of the ? operator, python matches the first sub-string that is given by the regular expression.

Technically, ? Causes the resulting RE to match 0 or 1 repetitions of the preceding RE. example : ab? will match either a or ab. So, Here, w.*?m will match minimum number of characters after w(included) that ends with m(included).

>>> s = '''I wish I may, I wish I might
... Have a dish of fish tonight.'''
>>>
>>> import re
>>> m = re.search('w.*m', s)    #GREEDY SEARCH
>>> print(m.group())
wish I may, I wish I m
>>> m = re.search('w.*?m', s)   #NON GREEDY SEARCH
>>> print(m.group())
wish I m

Read more about REGULAR EXPRESSIONS here

gaurav
  • 136
  • 1
  • 6