77

I have a list of regexes in python, and a string. Is there an elegant way to check if the at least one regex in the list matches the string? By elegant, I mean something better than simply looping through all of the regexes and checking them against the string and stopping if a match is found.

Basically, I had this code:

list = ['something','another','thing','hello']
string = 'hi'
if string in list:
  pass # do something
else:
  pass # do something else

Now I would like to have some regular expressions in the list, rather than just strings, and I am wondering if there is an elegant solution to check for a match to replace if string in list:.

Thanks in advance.

Alan Moore
  • 71,299
  • 12
  • 93
  • 154
houbysoft
  • 31,018
  • 23
  • 95
  • 154

5 Answers5

109
import re

regexes = [
    "foo.*",
    "bar.*",
    "qu*x"
    ]

# Make a regex that matches if any of our regexes match.
combined = "(" + ")|(".join(regexes) + ")"

if re.match(combined, mystring):
    print "Some regex matched!"
Ned Batchelder
  • 345,440
  • 70
  • 544
  • 649
103
import re

regexes = [
    # your regexes here
    re.compile('hi'),
#    re.compile(...),
#    re.compile(...),
#    re.compile(...),
]

mystring = 'hi'

if any(regex.match(mystring) for regex in regexes):
    print 'Some regex matched!'
nosklo
  • 205,639
  • 55
  • 286
  • 290
  • If working in python 2.4, you won't have `any` - see http://stackoverflow.com/questions/3785433/python-backports-for-some-methods – Sam Heuck Sep 12 '13 at 19:42
  • 3
    How is this *"something better than simply looping through all of the regexes and checking them against the string and stopping if a match is found"*? I guess the combination of Ned's and this answer could be a winner though... – johndodo Jan 21 '14 at 15:26
11

Here's what I went for based on the other answers:

raw_list = ["some_regex","some_regex","some_regex","some_regex"]
reg_list = map(re.compile, raw_list)

mystring = "some_string"

if any(regex.match(mystring) for regex in reg_list):
    print("matched")
user5056973
  • 357
  • 3
  • 14
7

A mix of both Ned's and Nosklo's answers. Works guaranteed for any length of list... hope you enjoy

import re   
raw_lst = ["foo.*",
          "bar.*",
          "(Spam.{0,3}){1,3}"]

reg_lst = []
for raw_regex in raw_lst:
    reg_lst.append(re.compile(raw_regex))

mystring = "Spam, Spam, Spam!"
if any(compiled_reg.match(mystring) for compiled_reg in reg_lst):
    print("something matched")
Anderas
  • 591
  • 8
  • 15
2

If you loop over the strings, the time complexity would be O(n). A better approach would be combine those regexes as a regex-trie.

ospider
  • 7,510
  • 3
  • 40
  • 43