#ifndef STRINGFINDER_H #define STRINGFINDER_H #include #include #include #if defined(_WIN32) || defined (_WIN64) #include #elif __linux__ || MAC #include #endif namespace NSStringFinder { template, std::allocator>> struct TFoundedData { size_t m_unBeginPosition; size_t m_unEndPosition; StringType m_sValue; TFoundedData() : m_unBeginPosition(0), m_unEndPosition(0) {} }; template, std::allocator>> StringType FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const StringType& sDelimiter, const StringType& sEnding, const size_t& unStarting, size_t& unEndPosition) { if (sString.length() < unStarting) return StringType(); typedef const boost::iterator_range StringRange; StringRange itFound = boost::algorithm::ifind_first(StringRange(sString.begin() + unStarting, sString.end()), sProperty); if (itFound.empty()) return StringType(); StringRange itFoundBegin = boost::algorithm::ifind_first(StringRange(itFound.end(), sString.end()), sDelimiter); if (itFoundBegin.empty()) return StringType(); StringRange itFoundEnd = boost::algorithm::ifind_first(StringRange(itFoundBegin.end(), sString.end()), sEnding); if (itFoundEnd.empty()) return StringType(); unEndPosition += (itFoundEnd.end() - sString.begin()); StringType sValue{itFoundBegin.end(), itFoundEnd.begin()}; boost::algorithm::trim(sValue); return sValue; } std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting, size_t& unEndPosition) { return FindPropetyTemplate(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition); } std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting, size_t& unEndPosition) { return FindPropetyTemplate(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition); } std::string FindPropety(const std::string& sString, const std::string& sProperty, const std::string& sDelimiter, const std::string& sEnding, const size_t& unStarting = 0) { size_t unEndPosition = 0; return FindPropetyTemplate(sString, sProperty, sDelimiter, sEnding, unStarting, unEndPosition); } std::wstring FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::wstring& wsDelimiter, const std::wstring& wsEnding, const size_t& unStarting = 0) { size_t unEndPosition = 0; return FindPropetyTemplate(wsString, wsProperty, wsDelimiter, wsEnding, unStarting, unEndPosition); } template, std::allocator>> TFoundedData FindPropetyTemplate(const StringType& sString, const StringType& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting) { if (sString.length() < unStarting) return TFoundedData(); std::wstring wsRegexValue = L"(?i)" + std::wstring(sProperty.begin(), sProperty.end()); if (!arDelimiters.empty()) { wsRegexValue += L"\\s*["; for (const StringType& wsDelimiter : arDelimiters) wsRegexValue += std::wstring(wsDelimiter.begin(), wsDelimiter.end()) + L"|"; wsRegexValue.pop_back(); wsRegexValue += L"]{1}"; } if (!arEndings.empty()) { std::wstring wsEndingValue; for (const StringType& sEnding : arEndings) wsEndingValue += std::wstring(sEnding.begin(), sEnding.end()) + L"|"; wsEndingValue.pop_back(); wsRegexValue += L"\\s*(.[^" + wsEndingValue + L"]*)\\s*[" + wsEndingValue + L"]?"; } else wsRegexValue += L"\\s*(.*)[\\n|\\r]?"; boost::wregex oRegex(wsRegexValue); boost::match_results oResult; if (!boost::regex_search(sString.begin() + unStarting, sString.end(), oResult, oRegex)) return TFoundedData(); TFoundedData oData; oData.m_unBeginPosition = unStarting + oResult.position(); oData.m_unEndPosition = unStarting + oResult.position() + oResult.length(); oData.m_sValue = oResult[1]; boost::algorithm::trim(oData.m_sValue); return oData; } TFoundedData FindPropety(const std::string& sString, const std::string& sProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) { return FindPropetyTemplate(sString, sProperty, arDelimiters, arEndings, unStarting); } TFoundedData FindPropety(const std::wstring& wsString, const std::wstring& wsProperty, const std::vector& arDelimiters, const std::vector& arEndings, const size_t& unStarting = 0) { return FindPropetyTemplate(wsString, wsProperty, arDelimiters, arEndings, unStarting); } template void CutInside(StringType& sString, const StringEndgeType& sLeftEdge, const StringEndgeType& sRightEdge) { typedef const boost::iterator_range StringRange; StringRange itFoundBegin = boost::algorithm::ifind_first(StringRange(sString.begin(), sString.end()), sLeftEdge); if (itFoundBegin.empty()) return; StringRange itFoundEnd = boost::algorithm::ifind_first(StringRange(itFoundBegin.end(), sString.cend()), sRightEdge); if (itFoundEnd.empty()) { sString = StringType{itFoundBegin.end(), sString.cend()}; return; } sString = StringType{itFoundBegin.end(), itFoundEnd.begin()}; } template void CutInside(StringType& sString, const StringEdgeType& sEdge) { CutInside(sString, sEdge, sEdge); } template bool Equals(const StringFirstType& sFirstString, const StringSecondType& sSecondString) { return boost::iequals(sFirstString, sSecondString); } template bool EqualOf(const StringFirstType& sFirstString, const std::vector& arStrings) { for (const StringFirstType& sString : arStrings) if (boost::iequals(sFirstString, sString)) return true; return false; } template bool EqualOf(const StringFirstType& sFirstString, const std::initializer_list& arStrings) { for (const StringFirstType& sString : arStrings) if (boost::iequals(sFirstString, sString)) return true; return false; } template bool Find(const StringType& sString, const StringValueType& sValue) { return !boost::algorithm::ifind_first(sString, sValue).empty(); } int ToInt(const std::wstring& oValue, int nMinValue = 0) { boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))"); boost::match_results oResult; if (!boost::regex_search(oValue.begin(), oValue.end(), oResult, oRegex)) return nMinValue; const int nValue = std::stoi(*oResult.begin()); return std::max(nMinValue, nValue); } int ToDouble(const std::wstring& oValue, double dMinValue = 0.) { boost::wregex oRegex(LR"((-?\.\d+|-?\d+(\.\d+)?))"); boost::match_results oResult; if (!boost::regex_search(oValue.begin(), oValue.end(), oResult, oRegex)) return dMinValue; const double dValue = std::stod(*oResult.begin()); return (dValue >= dMinValue) ? dValue : dMinValue; } } #endif // STRINGFINDER_H