[boost]algorithm-erase_all_regex , split_regrex & regex_match

本文介绍使用Boost库处理TypeB报文中可能出现的分行情况,通过示例展示如何利用erase_all_regex去除分行标志及split_regex按指定规则进行分割。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在涉及解析TypeB报文时,出现了报文分行的情况(可能分也可能不分,可能在代码过长时,选择分行)。如果单纯是一行行的解析会比较繁琐,因为你不知道这行是不是分行了。但一般分行都是有规律的,因此选择采用boost库中的两个方法:erase_all_regex & split_regrex,头文件 boost/algorithm/string/regex.hpp

        template< 
            typename SequenceT, 
            typename CharT, 
            typename RegexTraitsT>
        inline void erase_all_regex( 
            SequenceT& Input,
            const basic_regex<CharT, RegexTraitsT>& Rx,
            match_flag_type Flags=match_default )
  • erase_all_regex
    erase_all_regex(string &, regex)
    删除满足regrex的子串,对原串进行修改
    Erase all substrings, matching given regex, from the input. The input string is modified in-place.
      template< 
            typename SequenceSequenceT, 
            typename RangeT,         
            typename CharT, 
            typename RegexTraitsT >
        inline SequenceSequenceT& split_regex(
            SequenceSequenceT& Result,
            const RangeT& Input,
            const basic_regex<CharT, RegexTraitsT>& Rx,
            match_flag_type Flags=match_default )
  • split_regex

split_regex(container &, string, regex)
以满足regex的字符串作为分隔符,对string进行分割,将结果存在container中。
Tokenize expression. This function is equivalent to C strtok. Input sequence is split into tokens, separated by separators. Separator is an every match of the given regex. Each part is copied and added as a new element to the output container. Thus the result container must be able to hold copies of the matches (in a compatible structure like std::string) or a reference to it (e.g. using the iterator range class). Examples of such a container are \c std::vector or \c std::list

        //1.调整TypeB报文结构,删除掉分行标志
        erase_all_regex(sTYPEB,boost::regex(
        "(\\r\\nSSR [A-Z]{4} [A-Z0-9]{2} ///)"
        "|(\\r\\nOSI [A-Z0-9]{2} ///)"
        ));

        //2.分行
        vector<string> vecLine;
        split_regex(vecLine, sTYPEB, boost::regex("\\r\\n"));  

对SSR TKNE HU ///和 OSI HU ///均进行分割。 或者((正则表达式1)|(正则表达式2))
原:
SSR TKNE MU HK1 SHAPEK5101Y26DEC-1ZHUYINGXIANG
SSR TKNE MU ///.7818757832922C1
OSI MU LNNM @@VlS&Oi@@
OSI MU ///1ZHUYINGXIANG
分割后:
SSR TKNE MU HK1 SHAPEK5101Y26DEC-1ZHUYINGXIANG.7818757832922C1
OSI MU LNNM @@VlS&Oi@@1ZHUYINGXIANG

  • regex_match

匹配
regex_match(string, regex)
验证string是否满足regex

template <class charT, class traits>
inline bool regex_match(const charT* str, 
                        const basic_regex<charT, traits>& e, 
                        match_flag_type flags = match_default)

头文件boost\regex\v4\regex_match.hpp

if (boost::regex_match(curLine.c_str(), boost::regex("OSI [A-Z0-9]{2} LNNM.*")))

筛选OSI MU LNNM @@VlS&Oi@@1ZHUYINGXIANG

#include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;vector&gt; #include &lt;map&gt; #include &lt;algorithm&gt; #include &lt;functional&gt; #include &lt;cctype&gt; #include &lt;memory&gt; #include &lt;variant&gt; #include &lt;regex&gt; #include &lt;cmath&gt; #include &lt;unordered_map&gt; #include &lt;locale&gt; #include &lt;iomanip&gt; #include &lt;sstream&gt; #ifdef _WIN32 #include &lt;windows.h&gt; #include &lt;io.h&gt; #include &lt;fcntl.h&gt; #endif // 基础类型定义 using Value = std::variant&lt;int, double, std::string, bool&gt;; using Row = std::vector&lt;Value&gt;; using Table = std::vector&lt;Row&gt;; using ColumnMap = std::unordered_map&lt;std::string, int&gt;; // 字符串处理函数 std::string trim(const std::string&amp; str) { // 去除字符串两端的空白字符 size_t first = str.find_first_not_of(&quot; \t\n\r\f\v&quot;); if (first == std::string::npos) return &quot;&quot;; size_t last = str.find_last_not_of(&quot; \t\n\r\f\v&quot;); return str.substr(first, (last - first + 1)); } // 改进的DBF编码转换函数 std::string convertDBFToUTF8(const std::string&amp; str) { #ifdef _WIN32 if (str.empty()) return str; // 尝试从GBK转换为UTF-8 int len = MultiByteToWideChar(936, 0, str.c_str(), -1, NULL, 0); if (len &gt; 0) { wchar_t* wstr = new wchar_t[len]; MultiByteToWideChar(936, 0, str.c_str(), -1, wstr, len); len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); if (len &gt; 0) { char* utf8Str = new char[len]; WideCharToMultiByte(CP_UTF8, 0, wstr, -1, utf8Str, len, NULL, NULL); std::string result(utf8Str); delete[] wstr; delete[] utf8Str; return result; } delete[] wstr; } return str; #else return str; // 非Windows平台直接返回 #endif } // 用于处理DBF字段名的函数 std::string processDBFFieldName(const char* name, size_t len) { std::string fieldName(name, len); fieldName = fieldName.substr(0, fieldName.find(&#39;\0&#39;)); fieldName = trim(fieldName); fieldName = convertDBFToUTF8(fieldName); return fieldName; } // 用于处理DBF字符串字段的函数 std::string processDBFString(const char* str, size_t len) { std::string result(str, len); result = trim(result); result = convertDBFToUTF8(result); return result; } struct FieldDescriptor { char name[11]; char type; uint32_t address; uint8_t length; uint8_t decimal; }; struct DBFHeader { uint8_t version; uint8_t last_update[3]; uint32_t num_records; uint16_t header_size; uint16_t record_size; }; // DBF 文件读取器 class DBFReader { public: DBFReader(const std::string&amp; filename) : filename(filename) {} bool read() { std::ifstream file(filename, std::ios::binary); if (!file) return false; // 读取文件头 file.read(reinterpret_cast&lt;char*&gt;(&amp;header), sizeof(DBFHeader)); // 读取字段描述 int num_fields = (header.header_size - sizeof(DBFHeader) - 1) / 32; for (int i = 0; i &lt; num_fields; ++i) { FieldDescriptor fd; file.read(reinterpret_cast&lt;char*&gt;(&amp;fd), sizeof(FieldDescriptor)); fields.push_back(fd); // 处理字段名 std::string fieldName = processDBFFieldName(fd.name, sizeof(fd.name)); columnMap[fieldName] = i; } // 跳过文件头结束符 file.seekg(header.header_size); // 读取记录 for (int i = 0; i &lt; header.num_records; ++i) { char delete_flag; file.read(&amp;delete_flag, 1); if (delete_flag == &#39;*&#39;) { file.seekg(header.record_size - 1, std::ios::cur); continue; // 跳过已删除记录 } Row row; for (size_t j = 0; j &lt; fields.size(); j++) { const auto&amp; field = fields[j]; char* buffer = new char[field.length + 1]; file.read(buffer, field.length); buffer[field.length] = &#39;\0&#39;; // 转换数据类型 Value value; switch (field.type) { case &#39;N&#39;: // 数值 case &#39;I&#39;: // 整数 case &#39;F&#39;: // 浮点数 { std::string numStr = trim(std::string(buffer)); if (numStr.empty()) { if (field.type == &#39;I&#39;) { value = 0; // 整数默认值 } else { value = 0.0; // 浮点数默认值 } } else if (field.decimal &gt; 0 || numStr.find(&#39;.&#39;) != std::string::npos) { try { value = std::stod(numStr); } catch (...) { value = 0.0; } } else { try { value = std::stoi(numStr); } catch (...) { value = 0; } } } break; case &#39;D&#39;: // 日期 (格式: YYYYMMDD) { std::string dateStr(buffer); if (dateStr.length() == 8 &amp;&amp; std::all_of(dateStr.begin(), dateStr.end(), ::isdigit)) { value = dateStr.substr(0, 4) + &quot;-&quot; + dateStr.substr(4, 2) + &quot;-&quot; + dateStr.substr(6, 2); } else { value = dateStr; } } break; case &#39;L&#39;: // 逻辑 { char c = std::toupper(buffer[0]); value = (c == &#39;T&#39; || c == &#39;Y&#39; || c == &#39;1&#39;); } break; case &#39;C&#39;: // 字符 case &#39;M&#39;: // 备注 default: { // 处理字符串字段 std::string str = processDBFString(buffer, field.length); value = str; } break; } row.push_back(value); delete[] buffer; } data.push_back(row); } return true; } const Table&amp; getData() const { return data; } const std::vector&lt;FieldDescriptor&gt;&amp; getFields() const { return fields; } const ColumnMap&amp; getColumnMap() const { return columnMap; } private: std::string parseDate(const char* buffer) { // 简单日期转换: YYYYMMDD -&gt; YYYY-MM-DD std::string date(buffer); if (date.length() == 8 &amp;&amp; std::all_of(date.begin(), date.end(), ::isdigit)) { return date.substr(0, 4) + &quot;-&quot; + date.substr(4, 2) + &quot;-&quot; + date.substr(6, 2); } return date; } std::string filename; DBFHeader header; std::vector&lt;FieldDescriptor&gt; fields; Table data; ColumnMap columnMap; }; // SQL 查询解析器 class SQLParser { public: enum TokenType { SELECT, FROM, WHERE, INSERT, INTO, VALUES, UPDATE, SET, DELETE_TOKEN, AND, OR, NOT, EQ, NEQ, LT, GT, LTE, GTE, COMMA, LPAREN, RPAREN, IDENTIFIER, STRING, NUMBER, BOOL, STAR, EOF_TOKEN }; struct Token { TokenType type; std::string value; // 添加构造函数以支持初始化列表 Token(TokenType t) : type(t) {} Token(TokenType t, const std::string&amp; v) : type(t), value(v) {} }; explicit SQLParser(const std::string&amp; sql) : sql(sql), pos(0) {} std::vector&lt;Token&gt; tokenize() { std::vector&lt;Token&gt; tokens; while (pos &lt; sql.size()) { char c = sql[pos]; if (std::isspace(c)) { pos++; continue; } // 处理标识符和关键字 if (std::isalpha(c) || c == &#39;_&#39;) { std::string ident; while (pos &lt; sql.size() &amp;&amp; (std::isalnum(sql[pos]) || sql[pos] == &#39;_&#39;)) { ident += sql[pos++]; } std::transform(ident.begin(), ident.end(), ident.begin(), ::toupper); if (ident == &quot;SELECT&quot;) tokens.push_back(Token(SELECT)); else if (ident == &quot;FROM&quot;) tokens.push_back(Token(FROM)); else if (ident == &quot;WHERE&quot;) tokens.push_back(Token(WHERE)); else if (ident == &quot;INSERT&quot;) tokens.push_back(Token(INSERT)); else if (ident == &quot;INTO&quot;) tokens.push_back(Token(INTO)); else if (ident == &quot;VALUES&quot;) tokens.push_back(Token(VALUES)); else if (ident == &quot;UPDATE&quot;) tokens.push_back(Token(UPDATE)); else if (ident == &quot;SET&quot;) tokens.push_back(Token(SET)); else if (ident == &quot;DELETE&quot;) tokens.push_back(Token(DELETE_TOKEN)); else if (ident == &quot;AND&quot;) tokens.push_back(Token(AND)); else if (ident == &quot;OR&quot;) tokens.push_back(Token(OR)); else if (ident == &quot;NOT&quot;) tokens.push_back(Token(NOT)); else if (ident == &quot;TRUE&quot; || ident == &quot;FALSE&quot;) { tokens.push_back(Token(BOOL, ident)); } else { tokens.push_back(Token(IDENTIFIER, ident)); } continue; } // 处理数字 if (std::isdigit(c) || c == &#39;.&#39;) { std::string num; bool hasDecimal = false; while (pos &lt; sql.size() &amp;&amp; (std::isdigit(sql[pos]) || sql[pos] == &#39;.&#39;)) { if (sql[pos] == &#39;.&#39;) { if (hasDecimal) break; hasDecimal = true; } num += sql[pos++]; } tokens.push_back(Token(NUMBER, num)); continue; } // 处理字符串 if (c == &#39;\&#39;&#39;) { pos++; std::string str; while (pos &lt; sql.size() &amp;&amp; sql[pos] != &#39;\&#39;&#39;) { if (sql[pos] == &#39;\\&#39; &amp;&amp; pos + 1 &lt; sql.size()) { pos++; switch (sql[pos]) { case &#39;n&#39;: str += &#39;\n&#39;; break; case &#39;t&#39;: str += &#39;\t&#39;; break; case &#39;r&#39;: str += &#39;\r&#39;; break; default: str += sql[pos]; break; } } else { str += sql[pos]; } pos++; } if (pos &lt; sql.size() &amp;&amp; sql[pos] == &#39;\&#39;&#39;) pos++; tokens.push_back(Token(STRING, str)); continue; } // 处理操作符 switch (c) { case &#39;*&#39;: tokens.push_back(Token(STAR)); break; case &#39;,&#39;: tokens.push_back(Token(COMMA)); break; case &#39;(&#39;: tokens.push_back(Token(LPAREN)); break; case &#39;)&#39;: tokens.push_back(Token(RPAREN)); break; case &#39;=&#39;: tokens.push_back(Token(EQ)); break; case &#39;&lt;&#39;: if (pos + 1 &lt; sql.size() &amp;&amp; sql[pos + 1] == &#39;&gt;&#39;) { tokens.push_back(Token(NEQ)); pos++; } else if (pos + 1 &lt; sql.size() &amp;&amp; sql[pos + 1] == &#39;=&#39;) { tokens.push_back(Token(LTE)); pos++; } else { tokens.push_back(Token(LT)); } break; case &#39;&gt;&#39;: if (pos + 1 &lt; sql.size() &amp;&amp; sql[pos + 1] == &#39;=&#39;) { tokens.push_back(Token(GTE)); pos++; } else { tokens.push_back(Token(GT)); } break; case &#39;!&#39;: if (pos + 1 &lt; sql.size() &amp;&amp; sql[pos + 1] == &#39;=&#39;) { tokens.push_back(Token(NEQ)); pos++; } break; } pos++; } tokens.push_back(Token(EOF_TOKEN)); return tokens; } private: std::string sql; size_t pos; }; // SQL 查询执行引擎 class SQLExecutor { public: SQLExecutor(DBFReader&amp; reader) : reader(reader) {} Table execute(const std::string&amp; sql) { SQLParser parser(sql); auto tokens = parser.tokenize(); if (tokens.empty()) return {}; switch (tokens[0].type) { case SQLParser::SELECT: return executeSelect(tokens); case SQLParser::INSERT: return executeInsert(tokens); case SQLParser::UPDATE: return executeUpdate(tokens); case SQLParser::DELETE_TOKEN: return executeDelete(tokens); default: std::cerr &lt;&lt; &quot;Unsupported SQL statement&quot; &lt;&lt; std::endl; return {}; } } private: // SELECT 查询执行 Table executeSelect(const std::vector&lt;SQLParser::Token&gt;&amp; tokens) { Table result; auto&amp; data = reader.getData(); auto&amp; fields = reader.getFields(); auto&amp; columnMap = reader.getColumnMap(); // 解析字段列表 std::vector&lt;std::string&gt; selectedColumns; size_t pos = 1; // 跳过SELECT if (pos &lt; tokens.size() &amp;&amp; tokens[pos].type == SQLParser::STAR) { for (const auto&amp; field : fields) { std::string fieldName = processDBFFieldName(field.name, sizeof(field.name)); selectedColumns.push_back(fieldName); } pos += 2; // 跳过 * 和 FROM } else { while (pos &lt; tokens.size() &amp;&amp; tokens[pos].type != SQLParser::FROM) { if (tokens[pos].type == SQLParser::IDENTIFIER) { selectedColumns.push_back(tokens[pos].value); } pos++; } if (pos &lt; tokens.size()) pos++; // 跳过FROM } // 解析表名 (忽略,因为只有一个表) if (pos &lt; tokens.size() &amp;&amp; tokens[pos].type == SQLParser::IDENTIFIER) { std::string tableName = tokens[pos].value; pos++; } // 解析WHERE条件 std::function&lt;bool(const Row&amp;)&gt; condition = [](const Row&amp;) { return true; }; if (pos &lt; tokens.size() &amp;&amp; tokens[pos].type == SQLParser::WHERE) { pos++; condition = parseCondition(tokens, pos, columnMap); } // 执行查询 for (const auto&amp; row : data) { if (condition(row)) { Row resultRow; for (const auto&amp; col : selectedColumns) { // 尝试直接匹配 auto it = columnMap.find(col); if (it != columnMap.end()) { resultRow.push_back(row[it-&gt;second]); } else { // 如果直接匹配失败,尝试其他可能的编码格式 bool found = false; for (const auto&amp; pair : columnMap) { // 比较去除空格后的字段名 std::string mapKey = pair.first; std::string reqKey = col; // 去除空格 mapKey.erase(std::remove(mapKey.begin(), mapKey.end(), &#39; &#39;), mapKey.end()); reqKey.erase(std::remove(reqKey.begin(), reqKey.end(), &#39; &#39;), reqKey.end()); if (mapKey == reqKey) { resultRow.push_back(row[pair.second]); found = true; break; } } if (!found) { resultRow.push_back(std::string(&quot;&quot;)); } } } result.push_back(resultRow); } } return result; } // INSERT 语句执行 Table executeInsert(const std::vector&lt;SQLParser::Token&gt;&amp; tokens) { size_t pos = 1; // 跳过INSERT if (tokens[pos].type != SQLParser::INTO) { std::cerr &lt;&lt; &quot;Expected INTO after INSERT&quot; &lt;&lt; std::endl; return {}; } pos++; // 跳过INTO if (tokens[pos].type != SQLParser::IDENTIFIER) { std::cerr &lt;&lt; &quot;Expected table name after INTO&quot; &lt;&lt; std::endl; return {}; } std::string tableName = tokens[pos++].value; if (tokens[pos].type != SQLParser::LPAREN) { std::cerr &lt;&lt; &quot;Expected &#39;(&#39; after table name&quot; &lt;&lt; std::endl; return {}; } pos++; // 跳过&#39;(&#39; // 解析列名 std::vector&lt;std::string&gt; columns; while (pos &lt; tokens.size() &amp;&amp; tokens[pos].type != SQLParser::RPAREN) { if (tokens[pos].type == SQLParser::IDENTIFIER) { columns.push_back(tokens[pos].value); } pos++; if (tokens[pos].type == SQLParser::COMMA) pos++; } pos++; // 跳过&#39;)&#39; if (tokens[pos].type != SQLParser::VALUES) { std::cerr &lt;&lt; &quot;Expected VALUES after column list&quot; &lt;&lt; std::endl; return {}; } pos++; // 跳过VALUES if (tokens[pos].type != SQLParser::LPAREN) { std::cerr &lt;&lt; &quot;Expected &#39;(&#39; after VALUES&quot; &lt;&lt; std::endl; return {}; } pos++; // 跳过&#39;(&#39; // 解析值 Row newRow; while (pos &lt; tokens.size() &amp;&amp; tokens[pos].type != SQLParser::RPAREN) { if (tokens[pos].type == SQLParser::STRING) { newRow.push_back(tokens[pos].value); } else if (tokens[pos].type == SQLParser::NUMBER) { if (tokens[pos].value.find(&#39;.&#39;) != std::string::npos) { newRow.push_back(std::stod(tokens[pos].value)); } else { newRow.push_back(std::stoi(tokens[pos].value)); } } else if (tokens[pos].type == SQLParser::BOOL) { newRow.push_back((tokens[pos].value == &quot;TRUE&quot;)); } else if (tokens[pos].type == SQLParser::IDENTIFIER) { // 假设为列名或其他不支持的类型,暂不处理 newRow.push_back(tokens[pos].value); } pos++; if (tokens[pos].type == SQLParser::COMMA) pos++; } pos++; // 跳过&#39;)&#39; // 验证列数与值数一致 if (columns.size() != newRow.size()) { std::cerr &lt;&lt; &quot;Column count does not match value count&quot; &lt;&lt; std::endl; return {}; } // 获取列映射 const auto&amp; columnMap = reader.getColumnMap(); const auto&amp; fields = reader.getFields(); // 构造完整行数据,按字段顺序填充 Row fullRow(fields.size()); for (size_t i = 0; i &lt; columns.size(); ++i) { auto it = columnMap.find(columns[i]); if (it == columnMap.end()) { std::cerr &lt;&lt; &quot;Unknown column: &quot; &lt;&lt; columns[i] &lt;&lt; std::endl; return {}; } fullRow[it-&gt;second] = newRow[i]; } // 添加新行到数据表 const_cast&lt;Table&amp;&gt;(reader.getData()).push_back(fullRow); // 返回新插入的行 Table result; result.push_back(fullRow); return result; } // UPDATE 语句执行 Table executeUpdate(const std::vector&lt;SQLParser::Token&gt;&amp; tokens) { size_t pos = 1; // 跳过UPDATE if (tokens[pos].type != SQLParser::IDENTIFIER) { std::cerr &lt;&lt; &quot;Expected table name after UPDATE&quot; &lt;&lt; std::endl; return {}; } std::string tableName = tokens[pos++].value; if (tokens[pos].type != SQLParser::SET) { std::cerr &lt;&lt; &quot;Expected SET after table name in UPDATE&quot; &lt;&lt; std::endl; return {}; } pos++; // 跳过SET // 解析更新字段 std::vector&lt;std::pair&lt;std::string, Value&gt;&gt; updates; while (pos &lt; tokens.size() &amp;&amp; tokens[pos].type == SQLParser::IDENTIFIER) { std::string colName = tokens[pos++].value; if (pos &lt; tokens.size() &amp;&amp; tokens[pos].type == SQLParser::EQ) { pos++; // 跳过= Value value; if (tokens[pos].type == SQLParser::STRING) { value = tokens[pos].value; } else if (tokens[pos].type == SQLParser::NUMBER) { if (tokens[pos].value.find(&#39;.&#39;) != std::string::npos) { value = std::stod(tokens[pos].value); } else { value = std::stoi(tokens[pos].value); } } else if (tokens[pos].type == SQLParser::BOOL) { value = (tokens[pos].value == &quot;TRUE&quot;); } pos++; // 跳过值 updates.push_back({colName, value}); } if (pos &lt; tokens.size() &amp;&amp; tokens[pos].type == SQLParser::COMMA) { pos++; // 跳过逗号 } } // 解析WHERE条件 std::function&lt;bool(const Row&amp;)&gt; condition = [](const Row&amp;) { return true; }; if (pos &lt; tokens.size() &amp;&amp; tokens[pos].type == SQLParser::WHERE) { pos++; condition = parseCondition(tokens, pos, reader.getColumnMap()); } // 执行更新 auto&amp; data = const_cast&lt;Table&amp;&gt;(reader.getData()); // 移除const const auto&amp; columnMap = reader.getColumnMap(); Table updatedRows; for (auto&amp; row : data) { if (condition(row)) { // 该行满足更新条件 for (const auto&amp; [colName, value] : updates) { auto it = columnMap.find(colName); if (it != columnMap.end()) { row[it-&gt;second] = value; } } updatedRows.push_back(row); } } return updatedRows; } // DELETE 语句执行 Table executeDelete(const std::vector&lt;SQLParser::Token&gt;&amp; tokens) { // 实现删除逻辑 std::cout &lt;&lt; &quot;DELETE operation executed&quot; &lt;&lt; std::endl; return {}; } public: // 解析WHERE条件 std::function&lt;bool(const Row&amp;)&gt; parseCondition( const std::vector&lt;SQLParser::Token&gt;&amp; tokens, size_t&amp; pos, const ColumnMap&amp; columnMap) { // 递归解析条件表达式 return parseExpression(tokens, pos, columnMap); } std::function&lt;bool(const Row&amp;)&gt; parseExpression( const std::vector&lt;SQLParser::Token&gt;&amp; tokens, size_t&amp; pos, const ColumnMap&amp; columnMap) { auto left = parseTerm(tokens, pos, columnMap); while (pos &lt; tokens.size()) { if (tokens[pos].type == SQLParser::AND) { pos++; auto right = parseTerm(tokens, pos, columnMap); return [=](const Row&amp; row) { return left(row) &amp;&amp; right(row); }; } else if (tokens[pos].type == SQLParser::OR) { pos++; auto right = parseTerm(tokens, pos, columnMap); return [=](const Row&amp; row) { return left(row) || right(row); }; } else { break; } } return left; } std::function&lt;bool(const Row&amp;)&gt; parseTerm( const std::vector&lt;SQLParser::Token&gt;&amp; tokens, size_t&amp; pos, const ColumnMap&amp; columnMap) { if (tokens[pos].type == SQLParser::LPAREN) { pos++; auto expr = parseExpression(tokens, pos, columnMap); if (tokens[pos].type == SQLParser::RPAREN) pos++; return expr; } if (tokens[pos].type == SQLParser::NOT) { pos++; auto expr = parseTerm(tokens, pos, columnMap); return [=](const Row&amp; row) { return !expr(row); }; } return parseComparison(tokens, pos, columnMap); } std::function&lt;bool(const Row&amp;)&gt; parseComparison( const std::vector&lt;SQLParser::Token&gt;&amp; tokens, size_t&amp; pos, const ColumnMap&amp; columnMap) { if (pos &gt;= tokens.size()) return [](const Row&amp;) { return false; }; std::string colName = tokens[pos].value; pos++; if (pos &gt;= tokens.size()) return [](const Row&amp;) { return false; }; SQLParser::TokenType op = tokens[pos].type; pos++; if (pos &gt;= tokens.size()) return [](const Row&amp;) { return false; }; Value value; if (tokens[pos].type == SQLParser::STRING) { value = tokens[pos].value; } else if (tokens[pos].type == SQLParser::NUMBER) { if (tokens[pos].value.find(&#39;.&#39;) != std::string::npos) { value = std::stod(tokens[pos].value); } else { value = std::stoi(tokens[pos].value); } } else if (tokens[pos].type == SQLParser::BOOL) { value = (tokens[pos].value == &quot;TRUE&quot;); } pos++; // 查找字段索引 int colIndex = -1; auto it = columnMap.find(colName); if (it != columnMap.end()) { colIndex = it-&gt;second; } else { // 如果直接查找失败,尝试其他匹配方式 for (const auto&amp; pair : columnMap) { std::string mapKey = pair.first; std::string reqKey = colName; // 去除空格后比较 mapKey.erase(std::remove(mapKey.begin(), mapKey.end(), &#39; &#39;), mapKey.end()); reqKey.erase(std::remove(reqKey.begin(), reqKey.end(), &#39; &#39;), reqKey.end()); if (mapKey == reqKey) { colIndex = pair.second; break; } } } if (colIndex == -1) { return [](const Row&amp;) { return false; }; } switch (op) { case SQLParser::EQ: return [=](const Row&amp; row) { return row[colIndex] == value; }; case SQLParser::NEQ: return [=](const Row&amp; row) { return row[colIndex] != value; }; case SQLParser::LT: return [=](const Row&amp; row) { return compareValues(row[colIndex], value) &lt; 0; }; case SQLParser::GT: return [=](const Row&amp; row) { return compareValues(row[colIndex], value) &gt; 0; }; case SQLParser::LTE: return [=](const Row&amp; row) { return compareValues(row[colIndex], value) &lt;= 0; }; case SQLParser::GTE: return [=](const Row&amp; row) { return compareValues(row[colIndex], value) &gt;= 0; }; default: return [](const Row&amp;) { return false; }; } } int compareValues(const Value&amp; a, const Value&amp; b) { if (a.index() != b.index()) { // 尝试转换为相同类型 if (std::holds_alternative&lt;int&gt;(a) &amp;&amp; std::holds_alternative&lt;double&gt;(b)) { return compareValues(Value(static_cast&lt;double&gt;(std::get&lt;0&gt;(a))), b); } if (std::holds_alternative&lt;double&gt;(a) &amp;&amp; std::holds_alternative&lt;int&gt;(b)) { return compareValues(a, Value(static_cast&lt;double&gt;(std::get&lt;0&gt;(b)))); } return 0; // 不同类型无法比较 } switch (a.index()) { case 0: // int return (std::get&lt;0&gt;(a) == std::get&lt;0&gt;(b)) ? 0 : (std::get&lt;0&gt;(a) &lt; std::get&lt;0&gt;(b)) ? -1 : 1; case 1: // double return (std::get&lt;1&gt;(a) == std::get&lt;1&gt;(b)) ? 0 : (std::get&lt;1&gt;(a) &lt; std::get&lt;1&gt;(b)) ? -1 : 1; case 2: // string return std::get&lt;2&gt;(a).compare(std::get&lt;2&gt;(b)); case 3: // bool return static_cast&lt;int&gt;(std::get&lt;3&gt;(a)) - static_cast&lt;int&gt;(std::get&lt;3&gt;(b)); default: return 0; } } DBFReader&amp; reader; }; // 结果打印函数 void printTable(const Table&amp; table, const std::vector&lt;std::string&gt;&amp; headers) { // 计算列宽 std::vector&lt;size_t&gt; widths(headers.size(), 0); for (size_t i = 0; i &lt; headers.size(); i++) { widths[i] = headers[i].size(); } for (const auto&amp; row : table) { for (size_t i = 0; i &lt; row.size(); i++) { size_t len = 0; std::visit([&amp;](const auto&amp; arg) { using T = std::decay_t&lt;decltype(arg)&gt;; if constexpr (std::is_same_v&lt;T, std::string&gt;) { len = arg.size(); } else if constexpr (std::is_same_v&lt;T, int&gt; || std::is_same_v&lt;T, double&gt;) { std::ostringstream oss; oss &lt;&lt; arg; len = oss.str().size(); } else if constexpr (std::is_same_v&lt;T, bool&gt;) { len = 5; // &quot;false&quot;的长度 } }, row[i]); widths[i] = std::max(widths[i], len); } } // 打印表头 for (size_t i = 0; i &lt; headers.size(); i++) { std::cout &lt;&lt; std::left &lt;&lt; std::setw(widths[i] + 2) &lt;&lt; headers[i]; } std::cout &lt;&lt; &quot;\n&quot;; for (size_t i = 0; i &lt; headers.size(); i++) { std::cout &lt;&lt; std::string(widths[i] + 2, &#39;-&#39;); } std::cout &lt;&lt; &quot;\n&quot;; // 打印数据 for (const auto&amp; row : table) { for (size_t i = 0; i &lt; row.size(); i++) { std::visit([&amp;](const auto&amp; arg) { using T = std::decay_t&lt;decltype(arg)&gt;; if constexpr (std::is_same_v&lt;T, std::string&gt;) { std::cout &lt;&lt; std::left &lt;&lt; std::setw(widths[i] + 2) &lt;&lt; arg; } else if constexpr (std::is_same_v&lt;T, int&gt;) { std::cout &lt;&lt; std::right &lt;&lt; std::setw(widths[i] + 2) &lt;&lt; arg; } else if constexpr (std::is_same_v&lt;T, double&gt;) { std::cout &lt;&lt; std::fixed &lt;&lt; std::setprecision(2) &lt;&lt; std::right &lt;&lt; std::setw(widths[i] + 2) &lt;&lt; arg; } else if constexpr (std::is_same_v&lt;T, bool&gt;) { std::cout &lt;&lt; std::right &lt;&lt; std::setw(widths[i] + 2) &lt;&lt; (arg ? &quot;true&quot; : &quot;false&quot;); } }, row[i]); } std::cout &lt;&lt; &quot;\n&quot;; } } int main() { #ifdef _WIN32 // 设置控制台代码页为UTF-8,支持中文输出 SetConsoleOutputCP(CP_UTF8); SetConsoleCP(CP_UTF8); // 设置本地化以支持宽字符输出 std::setlocale(LC_ALL, &quot;zh_CN.UTF-8&quot;); #endif // 读取DBF文件 DBFReader reader(&quot;d:\\employees.dbf&quot;); if (!reader.read()) { std::cerr &lt;&lt; &quot;Failed to read DBF file. Please make sure &#39;employees.dbf&#39; exists in the current directory.&quot; &lt;&lt; std::endl; // 列出当前目录下的文件以帮助调试 std::cout &lt;&lt; &quot;Files in current directory:&quot; &lt;&lt; std::endl; system(&quot;dir *.dbf&quot;); return 1; } std::cout &lt;&lt; &quot;DBF file read successfully.&quot; &lt;&lt; std::endl; // 创建SQL执行器 SQLExecutor executor(reader); // 显示字段信息 std::cout &lt;&lt; &quot;Fields in DBF file:&quot; &lt;&lt; std::endl; const auto&amp; fields = reader.getFields(); for (const auto&amp; field : fields) { std::string fieldName = processDBFFieldName(field.name, sizeof(field.name)); std::cout &lt;&lt; &quot; &quot; &lt;&lt; fieldName &lt;&lt; &quot; (type: &quot; &lt;&lt; field.type &lt;&lt; &quot;, length: &quot; &lt;&lt; (int)field.length &lt;&lt; &quot;)&quot; &lt;&lt; std::endl; } // 显示记录数量 std::cout &lt;&lt; &quot;Total records: &quot; &lt;&lt; reader.getData().size() &lt;&lt; std::endl; // 执行SQL查询 - 显示所有记录 std::cout &lt;&lt; &quot;\nSQL: SELECT * FROM employees\n&quot;; Table result = executor.execute(&quot;SELECT * FROM employees&quot;); // 准备表头 std::vector&lt;std::string&gt; headers; for (const auto&amp; field : reader.getFields()) { std::string fieldName = processDBFFieldName(field.name, sizeof(field.name)); headers.push_back(fieldName); } // 打印结果 printTable(result, headers); // 执行另一个查询 - 查询成绩大于80的学生 std::cout &lt;&lt; &quot;\nSQL: SELECT 姓名, 成绩 FROM employees WHERE 成绩 &gt; 80\n&quot;; result = executor.execute(&quot;SELECT 姓名, 成绩 FROM employees WHERE 成绩 &gt; 80&quot;); printTable(result, {&quot;姓名&quot;, &quot;成绩&quot;}); // 查询特定班级的学生 std::cout &lt;&lt; &quot;\nSQL: SELECT 学号, 姓名, 班组 FROM employees WHERE 班组 = &#39;一年一班 &#39;\n&quot;; result = executor.execute(&quot;SELECT 学号, 姓名, 班组 FROM employees WHERE 班组 = &#39;一年一班&#39;&quot;); printTable(result, {&quot;学号&quot;, &quot;姓名&quot;, &quot;班组&quot;}); return 0; }以上代码,数据显示输出有中文乱码,请修复代码
最新发布
08-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值