diff --git a/config.toml b/config.toml
index c8dae7e..c4b16f7 100644
--- a/config.toml
+++ b/config.toml
@@ -11,9 +11,12 @@ host = "Broadcaster"
anon = "Anonymous"
[chat.filters]
+# prepend strings with "re:" for regular expressions
+# e.g. ban = ["re:\\bmelons?\\b", "re:(https?://)?([^.]+?\\.)*?example\\.com\\S*"]
ban = [] # block message & ban poster
block = [] # block message
censor = [] # censor word in message
+ignore_case = true
tyranny = true # word filters don't apply to broadcaster
[secret_club]
diff --git a/website/chat.py b/website/chat.py
index 697c145..696cc45 100644
--- a/website/chat.py
+++ b/website/chat.py
@@ -139,10 +139,13 @@ def _comment(text, token, c_response, c_ciphertext, nonce):
reaction = None
for key in ['censor', 'block', 'ban']:
for word in filters[key]:
- word = escape(word) # escape for html
- word = re.escape(word) # escape for regex
- regex = r'\b{}\b'.format(word)
- markup, n = re.subn(regex, '[CENSORED]', markup, flags=re.IGNORECASE)
+ word = escape(word) # escape for html
+ if word.startswith('re:'):
+ regex = word[3:]
+ else:
+ word = re.escape(word) # escape for regex
+ regex = r'\b{}\b'.format(word)
+ markup, n = re.subn(regex, '[CENSORED]', markup, flags=re.IGNORECASE if filters['ignore_case'] else 0)
if n: reaction = key
# enact consequences of word filters
note = N_NONE