#include "stdafx.h" #include "RegexEdit.h" #include IMPLEMENT_DYNAMIC(CRegexEdit, CEdit) CRegexEdit::CRegexEdit() { m_enRegexType = RegexType::Alphanumeric; m_dMinValue = LDBL_MIN; m_dMaxValue = LDBL_MAX; } CRegexEdit::~CRegexEdit() { } void CRegexEdit::SetRegexType(RegexType enType) { m_enRegexType = enType; } void CRegexEdit::SetCustomRegex(const std::string& strCustomRegex) { m_strCustomRegex = strCustomRegex; } void CRegexEdit::SetValueRange(long double dMinValue, long double dMaxValue) { m_dMinValue = dMinValue; m_dMaxValue = dMaxValue; } void CRegexEdit::SetCustomComparator(std::function comparator) { m_customComparator = comparator; } void CRegexEdit::SetInvalidInputCallback(std::function callback) { m_invalidInputCallback = callback; } bool CRegexEdit::FindMatch(const std::string& pattern, std::string& foundText) { CString currentText; GetWindowText(currentText); std::string text(CT2A(currentText.GetString())); std::regex regexPattern(pattern); std::smatch match; if (std::regex_search(text, match, regexPattern)) { foundText = match.str(); return true; } return false; } void CRegexEdit::ReplaceMatch(const std::string& pattern, const std::string& replacement) { CString currentText; GetWindowText(currentText); std::string text(CT2A(currentText.GetString())); std::regex regexPattern(pattern); std::string result = std::regex_replace(text, regexPattern, replacement); SetWindowText(CString(result.c_str())); } std::regex CRegexEdit::GetCurrentRegex() const { switch (m_enRegexType) { case RegexType::Alphanumeric: return std::regex("^[a-zA-Z0-9]*$"); // ×ÖĸºÍÊý×Ö case RegexType::Letters: return std::regex("^[a-zA-Z]*$"); // Ö»ÔÊÐí×Öĸ case RegexType::Digits: return std::regex("^\\d*$"); // Ö»ÔÊÐíÊý×Ö case RegexType::Decimal: return std::regex("^[-+]?\\d+(\\.\\d+)?$"); // ÔÊÐíСÊýºÍÕûÊý case RegexType::Custom: return std::regex(m_strCustomRegex); // ×Ô¶¨ÒåÕýÔò default: return std::regex(".*"); // ĬÈÏÔÊÐíÊäÈëÈκÎÄÚÈÝ } } bool CRegexEdit::IsValueInRange(const std::string& strText) { try { if (m_enRegexType == RegexType::Digits || m_enRegexType == RegexType::Decimal) { if (strText.find('.') == std::string::npos) { int nValue = std::stoi(strText); return nValue >= static_cast(m_dMinValue) && nValue <= static_cast(m_dMaxValue); } else { double dValue = std::stod(strText); return dValue >= m_dMinValue && dValue <= m_dMaxValue; } } } catch (const std::invalid_argument&) { return false; } return true; } BEGIN_MESSAGE_MAP(CRegexEdit, CEdit) ON_WM_CHAR() END_MESSAGE_MAP() void CRegexEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // ´¦Àíɾ³ý¼üºÍÍ˸ñ¼ü if (nChar == VK_BACK || nChar == VK_DELETE) { CEdit::OnChar(nChar, nRepCnt, nFlags); return; } CString strCurrent; GetWindowText(strCurrent); // »ñÈ¡¹â±êµ±Ç°Î»Öà int nStartChar, nEndChar; GetSel(nStartChar, nEndChar); // »ñÈ¡µ±Ç°Ñ¡ÇøµÄÆðʼºÍ½áÊøÎ»Öà std::string strText(CT2A(strCurrent.GetBuffer())); strText.insert(strText.begin() + nStartChar, (char)nChar); bool bValid = m_customComparator ? m_customComparator(strText) : IsValueInRange(strText); if (std::regex_match(strText, GetCurrentRegex()) && bValid) { CEdit::OnChar(nChar, nRepCnt, nFlags); } else { if (m_invalidInputCallback) { m_invalidInputCallback(); } } }