1

I'm trying to use a regular expression to match a pattern in the middle of a string where the strings are also in a list. I can find the solution to one problem or the other, but confused on how to combine the two.

First off, I'm using this solution as a template. I added text after "cat" and "cow", so they are now "cat named bob" and "cow also named bob". The goal is to extract the word "named" from those two strings in the list, and return them as items in a list (e.g. ['named', 'named']).

mylist = ["dog", "cat named bob", "wildcat", "thundercat", "cow also named bob", "hooo"]
r = re.compile('named')
newlist = list(filter(r.search, mylist)) 
print(newlist)

If I use r.search or r.findall, however, I get the entire string, rather than just the middle part. If I use r.match, I get no results. I found a few Stack Overflow queries on searching in the middle of a string, but they don't seem to go well with the solution for finding matches in a string. I tried the following code, but it didn't work:

newlist = list(filter(r.match.group(1), mylist)) 

How would I combine these two tasks and extract text in the middle of a string inside of a list?

Ragnar Lothbrok
  • 1,045
  • 2
  • 16
  • 31

2 Answers2

1

Use list comprehension:

print([m.group() for m in map(r.search, mylist) if m])

This outputs:

['named', 'named']
blhsing
  • 91,368
  • 6
  • 71
  • 106
1

With filter(r.search, mylist), you just receive all items where there is a regex match anywhere inside an item. When you use filter(r.match, mylist), you only get items where the match is at the start of the string.

You may use

import re
mylist = ["dog", "cat named bob", "wildcat", "thundercat", "cow also named bob", "hooo"]
r = re.compile('named')
# You might gfo through the list, check if there is match 
# by running a re.search, and there is, extract it
newlist = [r.search(x).group() for x in mylist if r.search(x)]
print(newlist)
# Or, use map to get the matches first, and then 
# check if the object is not None and then retrieve the value
newlist = [x.group() for x in map(r.search, mylist) if x]
print(newlist)

See the Python demo

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • This solution applies the same search twice for every matching item in `mylist`, which seems wasteful. – blhsing Jul 18 '18 at 09:32
  • 1
    @blhsing Yes, `[x.group() for x in map(r.search, mylist) if x]` will only perform it once. I was looking to update the solution with `map`, but I see you already posted it. – Wiktor Stribiżew Jul 18 '18 at 09:35