QMap<QString, bool> result;
     foreach(IgnoreListItem item, ignoreList()) {
         if (item.type == SenderIgnore && pureMatch(item, hostmask)
-            && ((network.isEmpty() && channel.isEmpty()) || item.scope == GlobalScope || (item.scope == NetworkScope && scopeMatch(item.scopeRule, network))
-                || (item.scope == ChannelScope && scopeMatch(item.scopeRule, channel)))) {
+            && ((network.isEmpty() && channel.isEmpty()) || item.scope == GlobalScope || (item.scope == NetworkScope && scopeMatch(network, item.scopeRule))
+                || (item.scope == ChannelScope && scopeMatch(channel, item.scopeRule)))) {
             result[item.ignoreRule] = item.isActive;
 //      qDebug() << "matchingRulesForHostmask found: " << item.ignoreRule << "is active: " << item.isActive;
         }
 
         if (!rule.isEnabled)
             continue;
 
-        if (!rule.chanName.isEmpty() && !scopeMatch(rule.chanName, bufferName)) {
+        if (!rule.chanName.isEmpty()
+                && !scopeMatch(bufferName, rule.chanName, rule.isRegEx, rule.isCaseSensitive)) {
             // A channel name rule is specified and does NOT match the current buffer name, skip
             // this rule
             continue;
         if (rule.sender.isEmpty()) {
             senderMatch = true;
         } else {
-            if (rule.isRegEx) {
-                rx = QRegExp(rule.sender, rule.isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
-            } else {
-                rx = QRegExp(rule.sender, Qt::CaseInsensitive, QRegExp::Wildcard);
-            }
-            senderMatch = rx.exactMatch(msgSender);
+            // A sender name rule is specified, match according to scope rules.
+            senderMatch = scopeMatch(msgSender, rule.sender, rule.isRegEx, rule.isCaseSensitive);
         }
 
         if (nameMatch && senderMatch) {
 
         if (!item.isActive || item.type == CtcpIgnore)
             continue;
         if (item.scope == GlobalScope
-            || (item.scope == NetworkScope && scopeMatch(item.scopeRule, network))
-            || (item.scope == ChannelScope && scopeMatch(item.scopeRule, bufferName))) {
+            || (item.scope == NetworkScope && scopeMatch(network, item.scopeRule))
+            || (item.scope == ChannelScope && scopeMatch(bufferName, item.scopeRule))) {
             QString str;
             if (item.type == MessageIgnore)
                 str = msgContents;
     foreach(IgnoreListItem item, _ignoreList) {
         if (!item.isActive)
             continue;
-        if (item.scope == GlobalScope || (item.scope == NetworkScope && scopeMatch(item.scopeRule, network))) {
+        if (item.scope == GlobalScope || (item.scope == NetworkScope && scopeMatch(network, item.scopeRule))) {
             QString sender_;
             QStringList types = item.ignoreRule.split(QRegExp("\\s+"), QString::SkipEmptyParts);
 
 
 }
 
 
-bool scopeMatch(const QString &scopeRule, const QString &string)
+bool scopeMatch(const QString &string, const QString &scopeRule, const bool &isRegEx,
+                const bool &isCaseSensitive)
 {
+    // When isRegEx is false:
     // A match happens when the string does NOT match ANY inverted rules and matches AT LEAST one
     // normal rule, unless no normal rules exist (implicit wildcard match).  This gives inverted
     // rules higher priority regardless of ordering.
     //
+    // When isRegEx is true:
+    // A match happens when the normal regular expression matches.  If prefixed with '!', the match
+    // happens UNLESS the following regular expression matches.
+
     // TODO: After switching to Qt 5, use of this should be split into two parts, one part that
     // would generate compiled QRegularExpressions for match/inverted match, regenerating it on any
     // rule changes, and another part that would check each message against these compiled rules.
 
-    // Keep track if any matches are found
-    bool matches = false;
-    // Keep track if normal rules and inverted rules are found, allowing for implicit wildcard
-    bool normalRuleFound = false, invertedRuleFound = false;
-
-    // Split each scope rule by separator, ignoring empty parts
-    foreach(QString rule, scopeRule.split(";", QString::SkipEmptyParts)) {
-        // Trim whitespace from the start/end of the rule
-        rule = rule.trimmed();
-        // Ignore empty rules
-        if (rule.isEmpty())
-            continue;
+    // Cache case sensitivity
+    Qt::CaseSensitivity ruleExactCase = (isCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive);
 
+    if (isRegEx) {
+        // Regular expression tests
+        // -------
         // Check if this is an inverted rule (starts with '!')
-        if (rule.startsWith("!")) {
-            // Inverted rule found
-            invertedRuleFound = true;
-
+        if (scopeRule.startsWith("!")) {
             // Take the reminder of the string
-            QRegExp ruleRx(rule.mid(1), Qt::CaseInsensitive);
-            ruleRx.setPatternSyntax(QRegExp::Wildcard);
-            if (ruleRx.exactMatch(string)) {
-                // Matches an inverted rule, full rule cannot match
-                return false;
-            }
+            QRegExp ruleRx(scopeRule.mid(1), ruleExactCase);
+            // Matching an inverted rule: matched (true) implies rule failure (false)
+            return !ruleRx.exactMatch(string);
         } else {
-            // Normal rule found
-            normalRuleFound = true;
-
-            QRegExp ruleRx(rule, Qt::CaseInsensitive);
-            ruleRx.setPatternSyntax(QRegExp::Wildcard);
-            if (ruleRx.exactMatch(string)) {
-                // Matches a normal rule, full rule might match
-                matches = true;
-                // Continue checking in case other inverted rules negate this
+            QRegExp ruleRx(scopeRule, ruleExactCase);
+            // Matching a normal rule: matched (true) implies rule success (true)
+            return ruleRx.exactMatch(string);
+        }
+    } else {
+        // Wildcard expression tests
+        // -------
+        // Keep track if any matches are found
+        bool matches = false;
+        // Keep track if normal rules and inverted rules are found, allowing for implicit wildcard
+        bool normalRuleFound = false, invertedRuleFound = false;
+
+        // Split each scope rule by separator, ignoring empty parts
+        foreach(QString rule, scopeRule.split(";", QString::SkipEmptyParts)) {
+            // Trim whitespace from the start/end of the rule
+            rule = rule.trimmed();
+            // Ignore empty rules
+            if (rule.isEmpty())
+                continue;
+
+            // Check if this is an inverted rule (starts with '!')
+            if (rule.startsWith("!")) {
+                // Inverted rule found
+                invertedRuleFound = true;
+
+                // Take the reminder of the string
+                QRegExp ruleRx(rule.mid(1), ruleExactCase);
+                ruleRx.setPatternSyntax(QRegExp::Wildcard);
+                if (ruleRx.exactMatch(string)) {
+                    // Matches an inverted rule, full rule cannot match
+                    return false;
+                }
+            } else {
+                // Normal rule found
+                normalRuleFound = true;
+
+                QRegExp ruleRx(rule, ruleExactCase);
+                ruleRx.setPatternSyntax(QRegExp::Wildcard);
+                if (ruleRx.exactMatch(string)) {
+                    // Matches a normal rule, full rule might match
+                    matches = true;
+                    // Continue checking in case other inverted rules negate this
+                }
             }
         }
+        // No inverted rules matched, okay to match normally
+        // Return true if...
+        // ...we found a normal match
+        // ...implicit wildcard: we had inverted rules (that didn't match) and no normal rules
+        return matches || (invertedRuleFound && !normalRuleFound);
     }
-    // No inverted rules matched, okay to match normally
-    // Return true if...
-    // ...we found a normal match
-    // ...implicit wildcard: we had inverted rules (that didn't match) and no normal rules
-    return matches || (invertedRuleFound && !normalRuleFound);
 }
 
 
 /** Check if a scope rule matches a string
  *
+ * When isRegEx is false:
  * Checks that the string does NOT match ANY inverted rules (prefixed by '!'), then checks that
  * it matches AT LEAST one normal (non-inverted) rule.
  *
  * If only inverted rules are specified, it'll match so long as the string does not match any
  * inverted rules (implicit wildcard).
  *
- * @param scopeRule  A ';'-separated list of wildcard expressions, prefix of '!' inverts subrule
- * @param string     String to test, e.g. network/channel name
+ * When isRegEx is true:
+ * Checks that the string matches the entire scopeRule as a regular expression.  If scopeRule starts
+ * with a '!', check that the string does NOT match the regular expression.
+ *
+ * @param string           String to test, e.g. network/channel name
+ * @param scopeRule        ';'-separated list of wildcard expressions, prefix of '!' inverts subrule
+ * @param isRegEx          If true, treat entire scope rule as regular expression, not wildcards
+ * @param isCaseSensitive  If true, treat as case-sensitive, else case-insensitive
  * @return True if matches, otherwise false
  */
-bool scopeMatch(const QString &scopeRule, const QString &string);
+bool scopeMatch(const QString &string, const QString &scopeRule,
+                const bool &isRegEx = false, const bool &isCaseSensitive = false);
 
                 continue;
 
             if (!rule.chanName.isEmpty()
-                    && !scopeMatch(rule.chanName, msg.bufferInfo().bufferName())) {
+                    && !scopeMatch(msg.bufferInfo().bufferName(), rule.chanName,
+                                   rule.isRegExp, rule.caseSensitive)) {
                 // A channel name rule is specified and does NOT match the current buffer name, skip
                 // this rule
                 continue;
 
     table->verticalHeader()->hide();
     table->setShowGrid(false);
 
+    table->horizontalHeaderItem(CoreHighlightSettingsPage::EnableColumn)->setToolTip(
+                tr("Enable/disable this rule"));
+    table->horizontalHeaderItem(CoreHighlightSettingsPage::EnableColumn)->setWhatsThis(
+                table->horizontalHeaderItem(CoreHighlightSettingsPage::EnableColumn)->toolTip());
+
+    table->horizontalHeaderItem(CoreHighlightSettingsPage::NameColumn)->setToolTip(
+                tr("Phrase to match"));
+    table->horizontalHeaderItem(CoreHighlightSettingsPage::NameColumn)->setWhatsThis(
+                table->horizontalHeaderItem(CoreHighlightSettingsPage::NameColumn)->toolTip());
+
     table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->setToolTip(
-                tr("<b>RegEx</b>: This option determines if the highlight rule should be "
-                   "interpreted as a <b>regular expression</b> or just as a keyword."));
+                tr("<b>RegEx</b>: This option determines if the highlight rule, <i>Sender</i>, and "
+                   "<i>Channel</i> should be interpreted as <b>regular expressions</b> or just as "
+                   "keywords."));
     table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->setWhatsThis(
                 table->horizontalHeaderItem(CoreHighlightSettingsPage::RegExColumn)->toolTip());
 
     table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->setToolTip(
-                tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
-                   "<b>case sensitive</b>."));
+                tr("<b>CS</b>: This option determines if the highlight rule, <i>Sender</i>, and "
+                   "<i>Channel</i> should be interpreted <b>case sensitive</b>."));
     table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->setWhatsThis(
                 table->horizontalHeaderItem(CoreHighlightSettingsPage::CsColumn)->toolTip());
 
+    table->horizontalHeaderItem(CoreHighlightSettingsPage::SenderColumn)->setToolTip(
+                tr("<p><b>Sender</b>: Semicolon separated list of <i>nick!ident@host</i> names, "
+                   "leave blank to match any nickname.</p>"
+                   "<p><i>Example:</i><br />"
+                   "<i>Alice!*; Bob!*@example.com; Carol*!*; !Caroline!*</i><br />"
+                   "would match on <i>Alice</i>, <i>Bob</i> with hostmask <i>example.com</i>, and "
+                   "any nickname starting with <i>Carol</i> except for <i>Caroline</i><br />"
+                   "<p>If only inverted names are specified, it will match anything except for "
+                   "what's specified (implicit wildcard).</p>"
+                   "<p><i>Example:</i><br />"
+                   "<i>!Announce*!*; !Wheatley!aperture@*</i><br />"
+                   "would match anything except for <i>Wheatley</i> with ident <i>aperture</i> or "
+                   "any nickname starting with <i>Announce</i></p>"));
+    table->horizontalHeaderItem(CoreHighlightSettingsPage::SenderColumn)->setWhatsThis(
+                table->horizontalHeaderItem(CoreHighlightSettingsPage::SenderColumn)->toolTip());
+
     table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->setToolTip(
-                tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
+                tr("<p><b>Channel</b>: Semicolon separated list of channel names, leave blank to "
+                   "match any name.</p>"
                    "<p><i>Example:</i><br />"
                    "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
-                   "would match on #foobar and on any channel starting with <i>#quassel</i> except "
-                   "for <i>#quasseldroid</i><br />"
+                   "would match on <i>#foobar</i> and any channel starting with <i>#quassel</i> "
+                   "except for <i>#quasseldroid</i><br />"
                    "<p>If only inverted names are specified, it will match anything except for "
                    "what's specified (implicit wildcard).</p>"
                    "<p><i>Example:</i><br />"
                    "<i>!#quassel*; !#foobar</i><br />"
-                   "would match anything except for #foobar or any channel starting with "
+                   "would match anything except for <i>#foobar</i> or any channel starting with "
                    "<i>#quassel</i></p>"));
     table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->setWhatsThis(
                 table->horizontalHeaderItem(CoreHighlightSettingsPage::ChanColumn)->toolTip());
         enableItem->setCheckState(Qt::Unchecked);
     enableItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
 
-    auto *chanNameItem = new QTableWidgetItem(chanName);
-
     auto *senderItem = new QTableWidgetItem(sender);
 
+    auto *chanNameItem = new QTableWidgetItem(chanName);
+
     enableItem->setToolTip(tr("Enable/disable this rule"));
     nameItem->setToolTip(tr("Phrase to match"));
     regexItem->setToolTip(
-                tr("<b>RegEx</b>: This option determines if the highlight rule should be "
-                   "interpreted as a <b>regular expression</b> or just as a keyword."));
+                tr("<b>RegEx</b>: This option determines if the highlight rule, <i>Sender</i>, and "
+                   "<i>Channel</i> should be interpreted as <b>regular expressions</b> or just as "
+                   "keywords."));
     csItem->setToolTip(
-                tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
-                   "<b>case sensitive</b>."));
+                tr("<b>CS</b>: This option determines if the highlight rule, <i>Sender</i>, and "
+                   "<i>Channel</i> should be interpreted <b>case sensitive</b>."));
     senderItem->setToolTip(
-                tr("<b>Sender</b>: This option specifies which sender to match.  Leave blank to "
-                   "match any nickname."));
+                tr("<p><b>Sender</b>: Semicolon separated list of <i>nick!ident@host</i> names, "
+                   "leave blank to match any nickname.</p>"
+                   "<p><i>Example:</i><br />"
+                   "<i>Alice!*; Bob!*@example.com; Carol*!*; !Caroline!*</i><br />"
+                   "would match on <i>Alice</i>, <i>Bob</i> with hostmask <i>example.com</i>, and "
+                   "any nickname starting with <i>Carol</i> except for <i>Caroline</i><br />"
+                   "<p>If only inverted names are specified, it will match anything except for "
+                   "what's specified (implicit wildcard).</p>"
+                   "<p><i>Example:</i><br />"
+                   "<i>!Announce*!*; !Wheatley!aperture@*</i><br />"
+                   "would match anything except for <i>Wheatley</i> with ident <i>aperture</i> or "
+                   "any nickname starting with <i>Announce</i></p>"));
     chanNameItem->setToolTip(
-                tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
+                tr("<p><b>Channel</b>: Semicolon separated list of channel names, leave blank to "
+                   "match any name.</p>"
                    "<p><i>Example:</i><br />"
                    "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
-                   "would match on #foobar and on any channel starting with <i>#quassel</i> except "
-                   "for <i>#quasseldroid</i><br />"
+                   "would match on <i>#foobar</i> and any channel starting with <i>#quassel</i> "
+                   "except for <i>#quasseldroid</i><br />"
                    "<p>If only inverted names are specified, it will match anything except for "
                    "what's specified (implicit wildcard).</p>"
                    "<p><i>Example:</i><br />"
                    "<i>!#quassel*; !#foobar</i><br />"
-                   "would match anything except for #foobar or any channel starting with "
+                   "would match anything except for <i>#foobar</i> or any channel starting with "
                    "<i>#quassel</i></p>"));
 
     int lastRow = ui.highlightTable->rowCount() - 1;
                 tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
                    "<p><i>Example:</i><br />"
                    "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
-                   "would match on #foobar and on any channel starting with <i>#quassel</i> except "
+                   "would match on #foobar and any channel starting with <i>#quassel</i> except "
                    "for <i>#quasseldroid</i><br />"
                    "<p>If only inverted names are specified, it will match anything except for "
                    "what's specified (implicit wildcard).</p>"
 
     ui.highlightTable->verticalHeader()->hide();
     ui.highlightTable->setShowGrid(false);
 
+
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::EnableColumn)->setToolTip(
+                tr("Enable/disable this rule"));
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::EnableColumn)->setWhatsThis(
+                ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::EnableColumn)->toolTip());
+
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::NameColumn)->setToolTip(
+                tr("Phrase to match"));
+    ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::NameColumn)->setWhatsThis(
+                ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::NameColumn)->toolTip());
+
     ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::RegExColumn)->setToolTip(
-                tr("<b>RegEx</b>: This option determines if the highlight rule should be "
-                   "interpreted as a <b>regular expression</b> or just as a keyword."));
+                tr("<b>RegEx</b>: This option determines if the highlight rule and <i>Channel</i> "
+                   "should be interpreted as <b>regular expressions</b> or just as keywords."));
     ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::RegExColumn)->setWhatsThis(
                 ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::RegExColumn)->toolTip());
 
     ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::CsColumn)->setToolTip(
-                tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
-                   "<b>case sensitive</b>."));
+                tr("<b>CS</b>: This option determines if the highlight rule and <i>Channel</i> "
+                   "should be interpreted <b>case sensitive</b>."));
     ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::CsColumn)->setWhatsThis(
                 ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::CsColumn)->toolTip());
 
     ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::ChanColumn)->setToolTip(
-                tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
+                tr("<p><b>Channel</b>: Semicolon separated list of channel names, leave blank to "
+                   "match any name.</p>"
                    "<p><i>Example:</i><br />"
                    "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
-                   "would match on #foobar and on any channel starting with <i>#quassel</i> except "
-                   "for <i>#quasseldroid</i><br />"
+                   "would match on <i>#foobar</i> and any channel starting with <i>#quassel</i> "
+                   "except for <i>#quasseldroid</i><br />"
                    "<p>If only inverted names are specified, it will match anything except for "
                    "what's specified (implicit wildcard).</p>"
                    "<p><i>Example:</i><br />"
                    "<i>!#quassel*; !#foobar</i><br />"
-                   "would match anything except for #foobar or any channel starting with "
+                   "would match anything except for <i>#foobar</i> or any channel starting with "
                    "<i>#quassel</i></p>"));
     ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::ChanColumn)->setWhatsThis(
                 ui.highlightTable->horizontalHeaderItem(HighlightSettingsPage::ChanColumn)->toolTip());
     enableItem->setToolTip(tr("Enable/disable this rule"));
     nameItem->setToolTip(tr("Phrase to match"));
     regexItem->setToolTip(
-                tr("<b>RegEx</b>: This option determines if the highlight rule should be "
-                   "interpreted as a <b>regular expression</b> or just as a keyword."));
+                tr("<b>RegEx</b>: This option determines if the highlight rule and <i>Channel</i> "
+                   "should be interpreted as <b>regular expressions</b> or just as keywords."));
     csItem->setToolTip(
-                tr("<b>CS</b>: This option determines if the highlight rule should be interpreted "
-                   "<b>case sensitive</b>."));
+                tr("<b>CS</b>: This option determines if the highlight rule and <i>Channel</i> "
+                   "should be interpreted <b>case sensitive</b>."));
     chanNameItem->setToolTip(
-                tr("<p><b>Channel</b>: Semicolon separated list of channel names.</p>"
+                tr("<p><b>Channel</b>: Semicolon separated list of channel names, leave blank to "
+                   "match any name.</p>"
                    "<p><i>Example:</i><br />"
                    "<i>#quassel*; #foobar; !#quasseldroid</i><br />"
-                   "would match on #foobar and on any channel starting with <i>#quassel</i> except "
-                   "for <i>#quasseldroid</i><br />"
+                   "would match on <i>#foobar</i> and any channel starting with <i>#quassel</i> "
+                   "except for <i>#quasseldroid</i><br />"
                    "<p>If only inverted names are specified, it will match anything except for "
                    "what's specified (implicit wildcard).</p>"
                    "<p><i>Example:</i><br />"
                    "<i>!#quassel*; !#foobar</i><br />"
-                   "would match anything except for #foobar or any channel starting with "
+                   "would match anything except for <i>#foobar</i> or any channel starting with "
                    "<i>#quassel</i></p>"));
 
     int lastRow = ui.highlightTable->rowCount()-1;
 
 <br />
 <i>#quassel*; #foobar; !#quasseldroid</i>
 <br />
-would match on #foobar and on any channel starting with <i>#quassel</i> except for <i>#quasseldroid</i>
+would match on <i>#foobar</i> and any channel starting with <i>#quassel</i> except for <i>#quasseldroid</i>
 <br />
 <p>If only inverted names are specified, it will match anything except for what's specified (implicit wildcard).</p>
 <p><i>Example:</i>
 <br />
 <i>!#quassel*; !#foobar</i>
 <br />
-would match anything except for #foobar or any channel starting with <i>#quassel</i></p></string>
+would match anything except for <i>#foobar</i> or any channel starting with <i>#quassel</i></p></string>
         </property>
        </widget>
       </item>