Ben Liu
Ben Liu

Reputation: 213

Find a substring with conditions with a regex

I want to return False only if the substring has alphabet letter(s) both before AND after it:

e.g. given the target 'at' and

strings = ['dad at home', 'eat apple', 'he never ate maple', 'because he hate it']

I'd like to return [True, True, True, False].

I have now:

def foo(p,i):
    if p.findall(i):
        return True
    return False

pat = re.compile(r'\bat\b')
[foo(pat,i) for i in strings]

which returns [True, False, False, False].

Upvotes: 2

Views: 319

Answers (4)

Laurent H.
Laurent H.

Reputation: 6526

Here is a readable one-line style solution using re.search and map functions:

import re

strings = ['dad at home', 'eat apple', 'he never ate maple', 'because he hate it']

s = list(map(lambda s: not re.search(r'[\w]at[\w]', s), strings))

print(s)   # [True, True, True, False]

Upvotes: 0

user8072518
user8072518

Reputation: 21

This would be a very very simple solution for your specific Problem.

def foo(text):
    for x in range(len(text)):
        if text[x] == 'a' and text[x+1] == 't':
            if text[x-1].isalnum() and text[x+2].isalnum():
                return False
    return True

Upvotes: 0

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627370

You may use re.search instead of re.findall since you only test a string for a match.

If you only need to match ASCII, [a-zA-Z] on both sides of a word will work.

Use

import re
strs = ['dad at home', 'eat apple', 'he never ate maple', 'because he hate it']

def foo(p,i):
    return False if p.search(i) else True

word = 'at'
pat = re.compile(r'[a-zA-Z]{}[a-zA-Z]'.format(word))
print([foo(pat,i) for i in strs])
# => [True, True, True, False]

See the Python demo

If you plan to work with Unicode letters, replace [a-zA-Z] with [^\W\d_]. In Python 3, re.U is used by default, in Python 2, you would need to add it.

Upvotes: 1

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11695

Try below regex

def foo(p,i):
    if p.findall(i):
        return True
    return False
pat = re.compile(r'.*([\w]at[\w]).*')
out  = [not foo(pat,i) for i in strings]
# [True, True, True, False]

Upvotes: 0

Related Questions