From: Kyle Fuller Date: Tue, 23 Dec 2014 22:01:47 +0000 (+0000) Subject: Match on word-boundaries X-Git-Tag: 1.0.0~11 X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=eaa88e6c515c55c3f75308443fec78a72772a5e5;p=znc-palaver.git Match on word-boundaries Closes #6 --- diff --git a/palaver.cpp b/palaver.cpp index 49afcf7..a3b2301 100644 --- a/palaver.cpp +++ b/palaver.cpp @@ -7,6 +7,13 @@ #define REQUIRESSL +#if defined(__has_include) +#if __has_include() +#define HAS_REGEX +#include +#endif +#endif + #include #include #include @@ -31,6 +38,27 @@ const char *kPLVIgnoreChannelKey = "IGNORE-CHANNEL"; const char *kPLVIgnoreNickKey = "IGNORE-NICK"; +#ifdef HAS_REGEX +/// Escape all non-alphanumeric characters or special characters in pattern. +CString re_escape(const CString& sString) { + CString sEscaped; + + for (const char& character : sString) { + if (isalpha(character) || isdigit(character)) { + sEscaped += character; + } else if (character == '\x00') { + sEscaped += "\\000"; + } else { + sEscaped += "\\"; + sEscaped += character; + } + } + + return sEscaped; +} +#endif + + typedef enum { StatusLine = 0, Headers = 1, @@ -396,17 +424,29 @@ public: for (VCString::const_iterator it = m_vMentionKeywords.begin(); it != m_vMentionKeywords.end(); ++it) { - const CString& sKeyword = *it; + CString sKeyword = *it; if (sKeyword.Equals("{nick}")) { - if (sMessage.find(sNick) != std::string::npos) { - bResult = true; - break; - } - } else if (sMessage.find(sKeyword) != std::string::npos) { + sKeyword = sNick; + } + +#ifdef HAS_REGEX + std::smatch match; + std::regex expression = std::regex("\\b" + re_escape(sKeyword) + "\\b", + std::regex_constants::ECMAScript | std::regex_constants::icase); + + std::regex_search(sMessage, match, expression); + + if (!match.empty()) { bResult = true; break; } +#else + if (sMessage.find(sKeyword) != std::string::npos) { + bResult = true; + break; + } +#endif } return bResult;