gpt4 book ai didi

c++ - 使用 C++ 或 Qt 将 SQL LIKE 表达式转换为正则表达式

转载 作者:行者123 更新时间:2023-11-27 22:53:59 27 4
gpt4 key购买 nike

我有这样的查询:

SELECT a, b, c
FROM T
WHERE ( a LIKE 'f%' OR b LIKE 'f%' OR c LIKE 'f%' )

当然,原始查询更复杂,过滤器更复杂。

我需要确定在哪个字段中匹配 a、b 或 c
基于此,我使用 Qt a 可以将结果与正则表达式进行比较。

但是如何将 LIKE 中的表达式转换为正则表达式。

this文章提供了部分解决方案。但可能存在更全面的例子?

PS:(回答评论中的问题)。

  • 我处理不同的 DBMS(PostgreSQL、SQL Server、MySQL),并不是所有的数据库都内置正则表达式支持
  • 我想找到像这样的匹配:

    const QString valueA( GetValueFromQuery() );
    if( valueA.contains( QRegExp( _CONVERTED_EXPRESSION_ )) {}

  • 在链接的帖子中描述了一个手工制作的解决方案。我想找到其他行之有效的解决方案。

最佳答案

虽然我仍然更喜欢将 LIKE 部分的结果添加到结果集中的解决方案,但这可能会满足您的需求。

此代码仍可能包含错误且未优化:

#include <algorithm>
#include <string>
#include <map>
#include <iostream>
#include <sstream>

std::string& replace_all(std::string& str, const std::string& old_value, const std::string& new_value)
{
std::string::size_type pos = 0;
while ((pos = str.find(old_value, pos)) != std::string::npos)
{
str.replace(pos, old_value.size(), new_value);
pos += new_value.size() - old_value.size() + 1;
}
return str;
}

std::map<std::string, std::string> extractCharacterRanges(std::string& str)
{
std::map<std::string, std::string> ranges;

int rangeID = 0;
std::string::size_type startPos = 0;
std::string::size_type endPos = 0;

while ((startPos = str.find("[", startPos)) != std::string::npos && (endPos = str.find("]", startPos + 1)) != std::string::npos)
{
std::stringstream ss;
ss << "[[" << rangeID << "]]";
std::string chars = str.substr(startPos + 1, endPos - startPos - 1);
str.replace(startPos, chars.size() + 2, ss.str());
rangeID++;
startPos += ss.str().size();

replace_all(chars, "[", "\\[");
replace_all(chars, "]", "\\]");
ranges[ss.str()] = "[" + chars + "]";
}

int open = 0;
std::string::size_type searchPos = 0;
startPos = 0; endPos = 0;
do
{
startPos = str.find("[", searchPos);
endPos = str.find("]", searchPos);

if (startPos == std::string::npos && endPos == std::string::npos)
break;

if (startPos < endPos || endPos == std::string::npos)
{
open++;
searchPos = startPos + 1;
}
else
{
if (open <= 0)
{
str.replace(endPos, 1, "\\]");
searchPos = endPos + 2;
}
else
{
open--;
searchPos = endPos + 1;
}
}
} while (searchPos < str.size());
return ranges;
}


std::string sqllike_to_regex(std::string sqllike)
{
replace_all(sqllike, ".", "\\.");
replace_all(sqllike, "^", "\\^");
replace_all(sqllike, "$", "\\$");
replace_all(sqllike, "+", "\\+");
replace_all(sqllike, "?", "\\?");
replace_all(sqllike, "(", "\\(");
replace_all(sqllike, ")", "\\)");
replace_all(sqllike, "{", "\\{");
replace_all(sqllike, "}", "\\}");
replace_all(sqllike, "\\", "\\\\");
replace_all(sqllike, "|", "\\|");
replace_all(sqllike, ".", "\\.");
replace_all(sqllike, "*", "\\*");
std::map<std::string, std::string> ranges = extractCharacterRanges(sqllike); //Escapes [ and ] where necessary
replace_all(sqllike, "%", ".*");
replace_all(sqllike, "_", ".");
for (auto& range : ranges)
{
replace_all(sqllike, range.first, range.second);
}
return "^" + sqllike + "$";
}


int main() {
std::cout << sqllike_to_regex("f%") << std::endl;//^f.*$
std::cout << sqllike_to_regex("[A-Z]%") << std::endl;//^[A-Z].*$
std::cout << sqllike_to_regex("[[A-Z][asd]]") << std::endl;//^[\[A - Z][asd]\]$
std::cout << sqllike_to_regex("a]a") << std::endl;//^a\]a$
std::cout << sqllike_to_regex("[%] [[] ] % [_] _") << std::endl;//^[%] [\[] \] .* [_] .$
return 0;
}

关于c++ - 使用 C++ 或 Qt 将 SQL LIKE 表达式转换为正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34897842/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com