Sql 就像在 c++ 中的类似用法一样
Sql Like similar use in c++
我想问一个简单的问题,有没有办法在c ++中使用"喜欢"这样的东西
就像 '%s 我想要 c++ 中这样的东西,因为如果我希望用户在程序中找到一些东西,这只会匹配所有相关数据。
正则表达式可用于实现您想要的。但是,有两个问题:
1.)与简单的SQL LIKE
关键字相比,它们使用起来非常复杂。
2.) 它们只是 C++11 中的标准功能。如果你用"旧"C++编写,那么你就必须使用Boost.Regex库。
然而。。。
查看 w3schools.com 中非常基本的LIKE
示例,实际上您可以使用普通的 std::string 函数以简单的C++实现其中的许多示例。
例如,让我们看一下:
SELECT * FROM Customers WHERE City LIKE '%s';
这只是意味着对于每个字符串,您查看最后一个字符并检查它是否为"s":
std::string s;
// ...
if (!s.empty() && (s[s.size() - 1] == 's') {
// ...
}
或者这个:
SELECT * FROM Customers WHERE Country NOT LIKE '%land%';
在C++:
std::string s;
// ...
if (s.find("land") == std::string::npos) {
// ...
}
所以,最后,这真的取决于你到底想用LIKE
做什么。
您可以尝试使用boost's
字符串算法库,该算法库可以与std::string
一起使用。它还为您提供了使用 C++11 正则表达式的选项。有很多函数可以做有用的事情(请参阅文档),例如starts_with()
(或不区分大小写的版本istarts_with()
)
这是从SQL Lite复制的版本。
现在您可以使用: patternCompare("A*A","AxA");
//---------------------LIKE------------------------------
/*
** This lookup table is used to help decode the first byte of
** a multi-byte UTF8 character.
*/
static const unsigned char sqlite3Utf8Trans1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
};
typedef unsigned int u32;
typedef unsigned char u8;
u32 sqlite3Utf8Read(
const unsigned char **pz /* Pointer to string from which to read char */
){
unsigned int c;
/* Same as READ_UTF8() above but without the zTerm parameter.
** For this routine, we assume the UTF8 string is always zero-terminated.
*/
c = *((*pz)++);
if (c >= 0xc0){
c = sqlite3Utf8Trans1[c - 0xc0];
while ((*(*pz) & 0xc0) == 0x80){
c = (c << 6) + (0x3f & *((*pz)++));
}
if (c<0x80
|| (c & 0xFFFFF800) == 0xD800
|| (c & 0xFFFFFFFE) == 0xFFFE){
c = 0xFFFD;
}
}
return c;
}
/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE_SKIP_UTF8(zIn) {
if( (*(zIn++))>=0xc0 ){
while( (*zIn & 0xc0)==0x80 ){ zIn++; }
}
}
const unsigned char sqlite3UpperToLower[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197,
198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233,
234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
252, 253, 254, 255
};
# define GlobUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
/*
** Compare two UTF-8 strings for equality where the first string can
** potentially be a "glob" expression. Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
**
** '*' Matches any sequence of zero or more characters.
**
** '?' Matches exactly one character.
**
** [...] Matches one character from the enclosed list of
** characters.
**
** [^...] Matches one character not in the enclosed list.
**
** With the [...] and [^...] matching, a ']' character can be included
** in the list by making it the first character after '[' or '^'. A
** range of characters can be specified using '-'. Example:
** "[a-z]" matches any single lower-case letter. To match a '-', make
** it the last character in the list.
**
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]". Like this:
**
** abc[*]xyz Matches "abc*xyz" only
*/
static int patternCompare(
const u8 *zPattern, /* The glob pattern */
const u8 *zString
)
{
u32 c, c2;
int invert;
int seen;
const u8 matchOne = '?';
const u8 matchAll = '*';
const u8 matchSet = '[';
const u8 noCase =0;
int prevEscape = 0; /* True if the previous character was 'escape' */
u32 esc = 0;
//u32 esc; /* The escape character */
while ((c = sqlite3Utf8Read(&zPattern)) != 0){
if (c == matchAll && !prevEscape){
while ((c = sqlite3Utf8Read(&zPattern)) == matchAll
|| c == matchOne){
if (c == matchOne && sqlite3Utf8Read(&zString) == 0){
return 0;
}
}
if (c == 0){
return 1;
}
else if (c == esc){
c = sqlite3Utf8Read(&zPattern);
if (c == 0){
return 0;
}
}
else if (c == matchSet){
//assert(esc == 0); /* This is GLOB, not LIKE */
//assert(matchSet<0x80); /* '[' is a single-byte character */
while (*zString && patternCompare(&zPattern[-1], zString) == 0){
SQLITE_SKIP_UTF8(zString);
}
return *zString != 0;
}
while ((c2 = sqlite3Utf8Read(&zString)) != 0){
if (noCase){
GlobUpperToLower(c2);
GlobUpperToLower(c);
while (c2 != 0 && c2 != c){
c2 = sqlite3Utf8Read(&zString);
GlobUpperToLower(c2);
}
}
else{
while (c2 != 0 && c2 != c){
c2 = sqlite3Utf8Read(&zString);
}
}
if (c2 == 0) return 0;
if (patternCompare(zPattern, zString)) return 1;
}
return 0;
}
else if (c == matchOne && !prevEscape){
if (sqlite3Utf8Read(&zString) == 0){
return 0;
}
}
else if (c == matchSet){
u32 prior_c = 0;
//assert(esc == 0); /* This only occurs for GLOB, not LIKE */
seen = 0;
invert = 0;
c = sqlite3Utf8Read(&zString);
if (c == 0) return 0;
c2 = sqlite3Utf8Read(&zPattern);
if (c2 == '^'){
invert = 1;
c2 = sqlite3Utf8Read(&zPattern);
}
if (c2 == ']'){
if (c == ']') seen = 1;
c2 = sqlite3Utf8Read(&zPattern);
}
while (c2 && c2 != ']'){
if (c2 == '-' && zPattern[0] != ']' && zPattern[0] != 0 && prior_c>0){
c2 = sqlite3Utf8Read(&zPattern);
if (c >= prior_c && c <= c2) seen = 1;
prior_c = 0;
}
else{
if (c == c2){
seen = 1;
}
prior_c = c2;
}
c2 = sqlite3Utf8Read(&zPattern);
}
if (c2 == 0 || (seen ^ invert) == 0){
return 0;
}
}
else if (esc == c && !prevEscape){
prevEscape = 1;
}
else{
c2 = sqlite3Utf8Read(&zString);
if (noCase){
GlobUpperToLower(c);
GlobUpperToLower(c2);
}
if (c != c2){
return 0;
}
prevEscape = 0;
}
}
return *zString == 0;
}
http://www.cplusplus.com/reference/regex/regex_match/有一个你想要做什么的例子。 请参阅底部附近的代码第 9-10 行。
相关文章:
- 这个指针在c++中的用法
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 当C++中需要自动删除时,这是静态的正确用法吗?
- 为什么在C++中对链表这样做?(像堆叠一样处理它们)
- libstdc++ 文件系统中未初始化的用法?
- 堆栈和队列是否像C++中的数组一样传递?
- 复制和交换习惯用法与移动操作之间的交互
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 命名参数习惯用法和(抽象)基类
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 省略号在C++中的所有用法
- () 在 C++ 11 中的特殊而奇怪的用法?
- 构造函数的用法
- 模板类中自动的类用法不完整
- 访问数据成员(本身是对象)的数据成员,就好像它们是类成员一样
- 我们可以将集合的值存储在变量中吗?就像我们可以将数组的值存储在变量中一样
- 我如何在C++像在 Python 中一样实现 f 字符串?
- 这里的 = 运算符有什么用法?
- 自制的上衣:看起来一样,但不完全相同
- Sql 就像在 c++ 中的类似用法一样