/************************************************************************************************** * * Copyright (c) 2019-2026 Axera Semiconductor (Ningbo) Co., Ltd. All Rights Reserved. * * This source file is the property of Axera Semiconductor (Ningbo) Co., Ltd. and * may not be copied or distributed in any isomorphic form without the prior * written consent of Axera Semiconductor (Ningbo) Co., Ltd. * **************************************************************************************************/ #pragma once #include #include #include #include #include #include #include class TextCleaner { public: TextCleaner() = default; ~TextCleaner() = default; std::string run(const std::string& input_text) { if (input_text.empty()) return ""; // 全角转半角 std::string text = _fullwidth_to_halfwidth(input_text); // 1. 替换连续空白字符 std::regex ws_re(R"(\s+)"); text = std::regex_replace(text, ws_re, " "); // 2. 去除首尾空白 auto not_whitespace = [](unsigned char ch) { return !std::isspace(ch); }; // 找到首尾非空白字符 auto begin = std::find_if(text.begin(), text.end(), not_whitespace); if (begin == text.end()) { return ""; // 全是空白字符 } auto end = std::find_if(text.rbegin(), text.rend(), not_whitespace).base(); // 创建子字符串视图 std::string trimmed(begin, end); // 3. 过滤字符 std::string filtered; filtered.reserve(trimmed.length()); // 遍历每个字符,只保留满足条件的字符: // 条件1:ord(char) >= 32 # ASCII值大于等于32(可打印字符和常见标点) // - ASCII 0-31是控制字符(如换行符、回车符、制表符等) // - ASCII 32是空格 // - ASCII 33-126是可打印字符 // 条件2:or char in '\n\r\t' # 或者字符是换行符、回车符、制表符 // 虽然这些字符的ASCII值<32,但我们特别允许它们通过 for (unsigned char ch : trimmed) { if (ch >= 32 || ch == '\n' || ch == '\r' || ch == '\t') { filtered.push_back(static_cast(ch)); } } return filtered; } private: // 全角字符转半角 std::string _fullwidth_to_halfwidth(const std::string& input) { std::string result; result.reserve(input.length()); // 预分配内存 // 全角到半角的映射表(UTF-8编码) // 注意:全角字符通常是3字节的UTF-8编码 static const std::unordered_map full_to_half = { // 中文标点 {"。", "."}, // 全角句号 {"!", "!"}, // 全角感叹号 {"?", "?"}, // 全角问号 {";", ";"}, // 全角分号 {",", ","}, // 全角逗号 {"、", ","}, // 全角顿号(转换为逗号) {":", ":"}, // 全角冒号 {""", "\""}, // 全角双引号 {"'", "'"}, // 全角单引号 {"(", "("}, // 全角左括号 {")", ")"}, // 全角右括号 {"【", "["}, // 全角左方括号 {"】", "]"}, // 全角右方括号 {"《", "<"}, // 全角左书名号 {"》", ">"}, // 全角右书名号 // 全角空格(通常用于中文排版) {" ", " "}, // 全角空格转半角空格 // 全角字母和数字(A-Z, a-z, 0-9) {"A", "A"}, {"B", "B"}, {"C", "C"}, {"D", "D"}, {"E", "E"}, {"F", "F"}, {"G", "G"}, {"H", "H"}, {"I", "I"}, {"J", "J"}, {"K", "K"}, {"L", "L"}, {"M", "M"}, {"N", "N"}, {"O", "O"}, {"P", "P"}, {"Q", "Q"}, {"R", "R"}, {"S", "S"}, {"T", "T"}, {"U", "U"}, {"V", "V"}, {"W", "W"}, {"X", "X"}, {"Y", "Y"}, {"Z", "Z"}, {"a", "a"}, {"b", "b"}, {"c", "c"}, {"d", "d"}, {"e", "e"}, {"f", "f"}, {"g", "g"}, {"h", "h"}, {"i", "i"}, {"j", "j"}, {"k", "k"}, {"l", "l"}, {"m", "m"}, {"n", "n"}, {"o", "o"}, {"p", "p"}, {"q", "q"}, {"r", "r"}, {"s", "s"}, {"t", "t"}, {"u", "u"}, {"v", "v"}, {"w", "w"}, {"x", "x"}, {"y", "y"}, {"z", "z"}, {"0", "0"}, {"1", "1"}, {"2", "2"}, {"3", "3"}, {"4", "4"}, {"5", "5"}, {"6", "6"}, {"7", "7"}, {"8", "8"}, {"9", "9"}, // 更多全角符号 {""", "\""}, // 全角双引号 {"'", "'"}, // 全角单引号 {""", "\""}, // 全角双引号 {"'", "'"}, // 全角单引号 {"~", "~"}, // 全角波浪号 {"@", "@"}, // 全角@ {"#", "#"}, // 全角# {"$", "$"}, // 全角$ {"%", "%"}, // 全角% {"&", "&"}, // 全角& {"*", "*"}, // 全角* {"+", "+"}, // 全角+ {"-", "-"}, // 全角- {"=", "="}, // 全角= {"\", "\\"}, // 全角反斜杠 {"|", "|"}, // 全角竖线 {"{", "{"}, // 全角左花括号 {"}", "}"}, // 全角右花括号 {"^", "^"}, // 全角^ {"_", "_"}, // 全角_ {"`", "`"}, // 全角` {"<", "<"}, // 全角小于号 {">", ">"}, // 全角大于号 }; size_t i = 0; while (i < input.length()) { // 检查是否是UTF-8多字节字符 unsigned char ch = static_cast(input[i]); if (ch < 128) { // ASCII字符,直接保留 result.push_back(input[i]); i++; } else { // 可能是UTF-8字符,尝试匹配 bool matched = false; // 检查最常见的3字节UTF-8字符(中文标点通常是3字节) if (i + 2 < input.length()) { std::string utf8_char = input.substr(i, 3); auto it = full_to_half.find(utf8_char); if (it != full_to_half.end()) { result += it->second; i += 3; matched = true; } } // 如果没有匹配到,保持原字符 if (!matched) { // 复制整个UTF-8字符(可能是2-4字节) int char_len = 0; if ((ch & 0xF0) == 0xF0) char_len = 4; // 4字节字符 else if ((ch & 0xE0) == 0xE0) char_len = 3; // 3字节字符 else if ((ch & 0xC0) == 0xC0) char_len = 2; // 2字节字符 else char_len = 1; // 不应该发生 result += input.substr(i, char_len); i += char_len; } } } return result; } };