a regular expression that matches
every element in the list
I see you've already got several answers based on the assumption that by "matches every element in the list" you actually meant "matches any element in the list" (the answers in questions are based on the |
"or" operator of regular expressions).
If you actually do want a RE to match every element of the list (as opposed to any single such element), then you might want to match them either in the same order as the list gives them (easy), or, in any order whatever (hard).
For in-order matching, '.*?'.join(list_patterns)
should serve you well (if the items are indeed to be taken as RE patterns - if they're to be taken as literal strings instead, '.*?'.join(re.escape(p) for p list_patterns)
).
For any-order matching, regular expressions, per se, offer no direct support. You could take all permutations of the list (e.g. with itertools.permutations
), join up each of them with '.*?'
, and join the whole with |
-- but that can produce a terribly long RE pattern as a result, because the number of permutations of N
items is N!
("N factorial" -- for example, for N equal 4, the permutations are 4 * 3 * 2 * 1 == 24
). Performance may therefore easily suffer unless the number of items in the list is known to be very, very small.
For a more general solution to the "match every item in arbitrary order" problem (if that's what you need), one with a performance and memory footprint that's still acceptable for decently large lengths of list, you need to give up on the target of making it all work with a single RE object, and inject some logic in the mix -- for example, make a list of RE objects with relist=[re.compile(p) for p in list_patterns]
, and check "they all match string s
, in any order" with all(r.search(s) for r in relist)
or the like.
Of course, if you need to make this latest approach work in a "duck-typing compatible way" with actual RE objects, that's not hard, e.g., if all you need is a search
method which returns a boolean result (since returning a "match object" would make no sense)...:
class relike(object):
def __init__(self, list_patterns):
self.relist = [re.compile(p) for p in list_patterns]
def search(self, s):
return all(r.search(s) for r in relist)