=== modified file 'xl/playlist.py' --- xl/playlist.py 2011-10-21 06:55:57 +0000 +++ xl/playlist.py 2011-11-27 06:50:14 +0000 @@ -1582,7 +1582,7 @@ 'value': value, 'op': op[0] } - elif op == "!=" or op == "!==": + elif op == "!=" or op == "!==" or op == "!~": s += '! %(field)s%(op)s"%(value)s"' % \ { 'field': field, === modified file 'xl/trax/search.py' --- xl/trax/search.py 2010-06-04 21:09:24 +0000 +++ xl/trax/search.py 2011-11-27 06:39:50 +0000 @@ -25,6 +25,7 @@ # from your version. import time +import re __all__ = ['TracksMatcher', 'search_tracks'] @@ -103,6 +104,22 @@ return self.content in value except TypeError: return False + +class _RegexMatcher(_Matcher): + """ + Condition for regular expression matches + """ + def __init__(self, tag, content, lower): + _Matcher.__init__(self, tag, content, lower) + self._re = re.compile(content) + + def _matches(self, value): + if not value: + return False + try: + return self._re.search( value ) is not None + except TypeError: + return False class _GtMatcher(_Matcher): """ @@ -308,6 +325,12 @@ content = content.strip().strip('"') matcher = _LtMatcher(tag, content, lower) matchers.append(matcher) + + elif "~" in token: + tag, content = token.split("~", 1) + content = content.strip().strip('"') + matcher = _RegexMatcher(tag, content, lower) + matchers.append(matcher) # plain keyword else: @@ -329,29 +352,34 @@ tokens = [] newsearch = "" in_quotes = False + in_regex = False n = 0 while n < len(search): c = search[n] if c == "\\": - n += 1 + if not in_regex: + n += 1 try: newsearch += search[n] except IndexError: pass elif in_quotes and c != "\"": newsearch += c + elif c == "~": + in_regex = True + newsearch += c elif c == "\"": in_quotes = not in_quotes # toggle #newsearch += c elif c in ["|", "!", "(", ")"]: newsearch += c elif c == " ": + in_regex = False tokens.append(newsearch) newsearch = "" else: newsearch += c n += 1 - return tokens def __red(self, tokens): === modified file 'xlgui/panel/playlists.py' --- xlgui/panel/playlists.py 2011-11-26 17:29:37 +0000 +++ xlgui/panel/playlists.py 2011-11-27 06:50:56 +0000 @@ -94,6 +94,8 @@ ('is not', EntryField), ('contains', EntryField), ('does not contain', EntryField), + ('regex', EntryField), + ('not regex', EntryField), ('is set', NullField), ('is not set', NullField), ]), @@ -102,6 +104,8 @@ ('is not', EntryField), ('contains', EntryField), ('does not contain', EntryField), + ('regex', EntryField), + ('not regex', EntryField), ('is set', NullField), ('is not set', NullField), ]), @@ -110,6 +114,8 @@ ('is not', EntryField), ('contains', EntryField), ('does not contain', EntryField), + ('regex', EntryField), + ('not regex', EntryField), ('is set', NullField), ('is not set', NullField), ]), @@ -156,6 +162,8 @@ ('is not', EntryField), ('contains', EntryField), ('does not contain', EntryField), + ('regex', EntryField), + ('not regex', EntryField), ]), (_('BPM'), [ ('is', EntryField), @@ -170,6 +178,8 @@ ('is not', EntryField), ('contains', EntryField), ('does not contain', EntryField), + ('regex', EntryField), + ('not regex', EntryField), ('is set', NullField), ('is not set', NullField), ]), @@ -194,6 +204,10 @@ N_('contains'): '=', # TRANSLATORS: True if haystack does not contain needle N_('does not contain'): '!=', + # TRANSLATORS: True if haystack matches regular expression + N_('regex'): '~', + # TRANSLATORS: True if haystack does not match regular expression + N_('not regex'): '!~', # TRANSLATORS: Example: rating >= 5 N_('at least'): '>=', # TRANSLATORS: Example: rating <= 3