diff options
Diffstat (limited to 'common/str.cpp')
-rw-r--r-- | common/str.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/common/str.cpp b/common/str.cpp index ad48ef6087..e849cb042d 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -283,6 +283,105 @@ void String::toUppercase() { _str[i] = toupper(_str[i]); } +bool String::regexMatch(const char *regex, bool skipSpaces) { + int pos = 0; + + if (regex[0] == '^') + return regexMatchPos(1, regex, 1, skipSpaces); + + do { + if (regexMatchPos(pos, regex, 0, skipSpaces)) + return true; + } while (_str[pos++]); + + return false; +} + +bool String::regexMatchCharacter(RegexMatchType type, char regexChar, char strChar) { + switch (type) { + case kRegexMatchAny: + return true; + + case kRegexMatchDigit: + return isdigit(strChar) != 0; + + case kRegexMatchSpace: + return isspace(strChar) != 0; + + case kRegexMatchAlphanum: + return isalnum(strChar) != 0; + + case kRegexMatchAlpha: + return isalpha(strChar) != 0; + + case kRegexMatchWord: + return isalnum(strChar) != 0 || strChar == '_'; + + case kRegexMatchCharacter: + return regexChar == strChar; + + default: + return false; + } +} + +bool String::regexMatchStar(RegexMatchType type, char regexChar, const char *regex, int regexPos, int strPos, bool skipSpaces) { + + do { + if (regexMatchPos(strPos, regex, regexPos, skipSpaces)) + return true; + } while (_str[strPos] && regexMatchCharacter(type, regexChar, _str[strPos++])); + + return false; +} + +bool String::regexMatchPos(int strPos, const char *regex, int regexPos, bool skipSpaces) { + RegexMatchType matchT = kRegexMatchCharacter; + + if (skipSpaces) { + while (isspace(_str[strPos])) + strPos++; + + while (isspace(regex[regexPos])) + regexPos++; + } + + if (regex[regexPos] == '\0') + return true; + + if (regex[regexPos] == '.') + matchT = kRegexMatchAny; + else if (regex[regexPos] == '[') { + String group; + while (regex[regexPos - 1] != ']') + group += regex[regexPos++]; + + regexPos--; + + if (group == "[digit]" || group == "[d]") + matchT = kRegexMatchDigit; + else if (group == "[space]" || group == "[s]") + matchT = kRegexMatchSpace; + else if (group == "[alnum]") + matchT = kRegexMatchAlphanum; + else if (group == "[alpha]") + matchT = kRegexMatchAlpha; + else if (group == "[word]") + matchT = kRegexMatchWord; + } + + if (regex[regexPos + 1] == '*') + return regexMatchStar(matchT, regex[regexPos], regex, regexPos + 2, strPos, skipSpaces); + + if (regex[regexPos] == '$' && regex[regexPos + 1] == 0) + return _str[strPos] == 0; + + if (_str[strPos] && regexMatchCharacter(matchT, regex[regexPos], _str[strPos])) + return regexMatchPos(strPos + 1, regex, regexPos + 1, skipSpaces); + + return false; +} + /** * Ensure that enough storage is available to store at least new_len * characters plus a null byte. In addition, if we currently share |