Sql 就像在 c++ 中的类似用法一样

Sql Like similar use in c++

本文关键字:用法 一样 c++ Sql      更新时间:2023-10-16

我想问一个简单的问题,有没有办法在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 行。