信息发布→ 登录 注册 退出

c++中如何判断字符串是否包含子串_c++字符串匹配方法

发布时间:2026-01-08

点击量:
c++kquote>最直接的方式是用 std::string::find 判断子串是否存在,它返回首次出现索引或 std::string::npos;注意不可与 -1 比较,应使用 npos;支持 string_view 优化性能,复杂模式需 regex。

std::string::find 判断子串是否存在最直接

这是 C++ 标准库中最常用、最轻量的方式。它返回子串首次出现的索引,没找到时返回 std::string::npos

注意:不要用 == -1 判断失败——std::string::npos 是无符号类型(通常是 size_t),值为 static_cast(-1),直接和 -1 比较会触发隐式转换警告或逻辑错误。

std::string s = "hello world";
std::string sub = "world";
if (s.find(sub) != std::string::npos) {
    // 找到了
}
  • 时间复杂度平均 O(n+m),最坏 O(n×m),适用于大多数日常场景
  • 区分大小写,如需忽略大小写,得先转小写再查,或手写遍历比较
  • 不支持通配符或正则,纯字面量匹配

需要更高效匹配时考虑 std::string_view::find

如果原始字符串是只读的、生命周期可控(比如来自函数参数或常量字符串字面量),用 std::string_view 替代 std::string 能避免拷贝开销,find 行为一致但更快。

std::string_view sv = "The quick brown fox";
if (sv.find("fox") != std::string_view::npos) {
    // 成功
}
  • std::string_view 不拥有数据,构造零成本
  • C++17 起可用;C++14 及更早需自行实现类似视图或坚持用 std::string
  • 不能用于需要修改内容或存储长期引用的场景(因底层数据可能已析构)

要找所有匹配位置或支持复杂模式就上 std::regex

当需求超出“是否包含”——比如要找全部出现位置、提取捕获组、支持 .* 或字符类——std::regex 是标准方案,但代价明显更高。

std::string text = "a1b2c3";
std::regex pattern(R"(\d)");
auto begin = std::sregex_iterator(text.begin(), text.end(), pattern);
auto end = std::sregex_iterator();
for (auto it = begin; it != end; ++it) {
    std::cout << it->str() << "\n"; // 输出 1, 2, 3
}
  • 编译正则表达式有开销,频繁使用建议缓存 std::regex 对象
  • 不同编译器对 std::regex 的实现质量差异大(尤其 GCC libstdc++ 历史上有 bug 和性能问题)
  • 简单子串查找用正则属于杀鸡用牛刀,运行时慢一个数量级以上

自定义函数做大小写不敏感查找要注意 locale 陷阱

标准库没有内置 case-insensitive find,常见做法是转小写后查,但直接用 std::tolower 处理多字节字符(如 UTF-8 中文、德语 ß)会出错——它只对单字节 char 安全。

  • 若确定输入是 ASCII,可安全用 std::tolower 遍历转换
  • 否则应使用 ICU、Boost.Locale 或 C++20 的 std::ranges::search + 自定义谓词
  • 简单起见,多数项目选择外部依赖 boost::algorithm::icontains,它内部处理了 locale 边界

真正容易被忽略的是:哪怕只是判断“是否包含”,在跨平台或国际化场景下,std::string::find 的语义仍是字节级精确匹配——它不理解 Unicode 码点、组合字符或正规化形式。这时候“包含”本身就需要重新定义。

标签:# bug  # 适用于  # 德语  # 这是  # 的是  # 是否存在  # 多字  # 要找  # 自定义  # 遍历  # 首次  # c++  # ASCII  # 对象  # Regex  # char  # 字符串  # 常量  # String  # 正则表达式  # 隐式转换  # 标准库  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!