diff options
author | Casey Dahlin <cdahlin@redhat.com> | 2008-12-22 02:56:11 -0500 |
---|---|---|
committer | Casey Dahlin <cdahlin@redhat.com> | 2008-12-22 02:56:11 -0500 |
commit | 456d0c14697cf19128a58b40053fa56d1daf21f5 (patch) | |
tree | d9498f474d2a35678fd5dbb907cbd325f91d1fe8 | |
parent | 8e1ee8d111b0ec5d7bf6b9e8f1dda833e35d30f2 (diff) | |
download | upstate-456d0c14697cf19128a58b40053fa56d1daf21f5.tar.gz upstate-456d0c14697cf19128a58b40053fa56d1daf21f5.tar.xz upstate-456d0c14697cf19128a58b40053fa56d1daf21f5.zip |
Add a pattern matching class
-rw-r--r-- | pattern.py | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/pattern.py b/pattern.py new file mode 100644 index 0000000..a1919b5 --- /dev/null +++ b/pattern.py @@ -0,0 +1,83 @@ +__docformat__ = 'restructuredtext' + +class Pattern: + """ + A pattern matches a string much like a regex. Our patterns have the + additional properties of being unionable and intersectable. + """ + + def __init__(self, positive_match, *args): + """ + `args` is a series of strings the pattern should match. If + `positive_match` is False, then `args` is a series of strings that + should *not* be matched. + """ + self.items = set(args) + self.invert = not positive_match + + def match(self, str): + """ + Determine if this Pattern matches `str` + """ + retval = str in self.items + if self.invert: retval = not retval + return retval + + def nonempty(self): + """ + Returns True if this pattern will *ever* match *any* string. + """ + if self.invert: return True + if len(self.items) > 0: return True + return False + + def singular(self): + """ + Returns True if this pattern will match *exactly one* string + """ + return not self.invert and len(self.items) == 1 + + def complement(self): + """ + Return a Pattern that matches anything this pattern *doesn't* match. + """ + return Pattern(self.invert, *self.items) + + def union(self, other): + """ + Return a Pattern that matches anything this pattern *or* the pattern + `other` would match. + """ + invert = True + if self.invert and other.invert: + items = self.items & other.items + elif not (self.invert or other.invert): + items = self.items | other.items + invert = False + else: + if self.invert: + items = self.items - other.items + else: + items = other.items - self.items + return Pattern(not invert, *items) + + def intersect(self, other): + """ + Return a Pattern that matches anything this pattern *and* the pattern + `other` would match. + """ + return self.complement().union(other.complement()).complement() + + def __str__(self): + if len(self.items) == 0: + if self.invert: + return "*" + else: + return "(-)" + if self.invert: + return "!(%s)" % "|".join(self.items) + else: + return "(%s)" % "|".join(self.items) + + def __repr__(self): + return str(self) |