#pragma once
#include "RegexFlags.hpp"
#include "RegexGroup.hpp"
#include "RegexMatchResult.hpp"
NAMESPACE_SOUP
{
struct Regex
{
RegexGroup group;
Regex(const std::string& pattern, const char* flags)
: Regex(pattern.data(), &pattern.data()[pattern.size()], parseFlags(flags))
{
}
Regex(const std::string& pattern, uint16_t flags = 0)
: Regex(pattern.data(), &pattern.data()[pattern.size()], flags)
{
}
Regex(const char* it, const char* end, uint16_t flags)
: group(it, end, flags)
{
}
Regex(const Regex& b)
: Regex(b.toString(), b.getFlags())
{
}
Regex() = default;
Regex(Regex&&) = default;
[[nodiscard]] static Regex fromFullString(const std::string& str);
[[nodiscard]] bool matches(const std::string& str) const noexcept;
[[nodiscard]] bool matches(const char* it, const char* end) const noexcept;
[[nodiscard]] bool matchesFully(const std::string& str) const noexcept;
[[nodiscard]] bool matchesFully(const char* it, const char* end) const noexcept;
[[nodiscard]] RegexMatchResult match(const std::string& str) const noexcept;
[[nodiscard]] RegexMatchResult match(const char* it, const char* end) const noexcept;
[[nodiscard]] RegexMatchResult match(const char* it, const char* begin, const char* end) const noexcept;
[[nodiscard]] RegexMatchResult match(RegexMatcher& m, const char* it) const noexcept;
[[nodiscard]] RegexMatchResult search(const std::string& str) const noexcept;
[[nodiscard]] RegexMatchResult search(const char* it, const char* end) const noexcept;
void replaceAll(std::string& str, const std::string& replacement) const;
[[nodiscard]] std::string toString() const SOUP_EXCAL
{
return group.toString();
}
[[nodiscard]] std::string toFullString() const SOUP_EXCAL
{
std::string str(1, '/');
str.append(toString());
str.push_back('/');
str.append(getFlagsString());
return str;
}
[[nodiscard]] uint16_t getFlags() const noexcept
{
return group.getFlags();
}
[[nodiscard]] std::string getFlagsString() const noexcept
{
return unparseFlags(group.getFlags());
}
[[nodiscard]] static constexpr uint16_t parseFlags(const char* flags)
{
uint16_t res = 0;
for (; *flags != '\0'; ++flags)
{
if (*flags == 'm')
{
res |= RE_MULTILINE;
}
else if (*flags == 's')
{
res |= RE_DOTALL;
}
else if (*flags == 'i')
{
res |= RE_INSENSITIVE;
}
else if (*flags == 'x')
{
res |= RE_EXTENDED;
}
else if (*flags == 'u')
{
res |= RE_UNICODE;
}
else if (*flags == 'U')
{
res |= RE_UNGREEDY;
}
else if (*flags == 'D')
{
res |= RE_DOLLAR_ENDONLY;
}
else if (*flags == 'n')
{
res |= RE_EXPLICIT_CAPTURE;
}
}
return res;
}
[[nodiscard]] static std::string unparseFlags(uint16_t flags);
[[nodiscard]] std::string toGraphvizDot() const SOUP_EXCAL;
};
namespace literals
{
inline Regex operator ""_r(const char* str, size_t len)
{
return Regex(std::string(str, len));
}
}
}