absl教程(四):Strings Library

absl/strings库提供了用于操作和比较字符串、将其他类型(例如整数)转换为字符串或为其他用途评估字符串的类和实用程序函数。此外,该 strings库还包含用于将数据存储在连续内存中的“类字符串”类的实用程序函数。

本文档概述了strings 库的亮点和一般用例。有关特定类、函数和字段的更多详细信息,请参阅特定头文件中的源文档。

尽管“字符串”通常被认为是 C++ 中的标准类型,但它们并不是内置类型,而是通过std::string类在标准库中提供 。从根本上说,一个字符串由一个大小和一个char字符数组组成 。

absl::string_view集装箱

通常,您需要访问字符串数据,但您不需要拥有它,也不需要修改它。出于这个原因,Abseil 定义了一个 absl::string_view类,它指向一个连续的字符范围,通常是另一个std::string双引号字符串文字、字符数组甚至另一个 的一部分或全部string_view。A string_view,顾名思义,提供其关联字符串数据的只读视图。

大多数 C++ 代码历来使用(较旧的)Cchar*指针类型或 C++std::string类来保存字符数据。希望使用这两种类型数据的方法如果想要避免复制数据,通常需要提供重载实现。Astring_view还充当接受两种类型字符数据的 API 的包装器;方法可以简单地声明它们接受absl::string_view

// A common use of string_view: Foo() can accept both char* and std::string via
// implicit conversion to string_view.
void Foo(absl::string_view s) { ... }

string_view对象非常轻量级,因此您应该始终在方法和函数中按值传递它们;不要通过const absl::string_view &. (传递absl::string_view而不是const absl::string_view &具有相同的算法复杂度,但由于寄存器分配和参数传递规则,在这种情况下按值传递通常更快。)

如上所述,因为string_view本身不拥有底层数据,所以它应该只用于只读数据。如果您需要向外部 API 用户提供字符串常量,例如:

// C++17: A read-only string in a header file.
inline constexpr absl::string_view kGreeting = "hi";
// C++11: A read-only string in a header file. Due to lifetime issues, a
// string_view is usually a poor choice for a return value (see below), but it's
// safe here because the static storage outlives it.
inline absl::string_view GetGreeting() {
  static constexpr char kGreeting[] = "hi";
  return kGreeting;
}

string_view如果您知道底层对象的生命周期长于string_view变量的生命周期,A也适用于局部 变量。但是,请注意将其绑定到临时值:

// BAD use of string_view: lifetime problem
absl::string_view sv = obj.ReturnAString();

// GOOD use of string_view: str outlives sv
std::string str = obj.ReturnAString();
absl::string_view sv = str;

由于生命周期问题,string_view对于返回值来说 a 通常是一个糟糕的选择,对于数据成员来说几乎总是一个糟糕的选择。如果您确实以这种方式使用了一个,则您有责任确保string_view不会超过它指向的对象。

Astring_view可以代表整个字符串或只是字符串的一部分。例如,拆分字符串时,std::vector<absl::string_view>是输出的自然数据类型。

注意:有关 的更多信息string_view,请参阅 abseil.io/tips/1

注意:有关常量的安全习语的更多信息,请参阅 abseil.io/tips/140

absl::StrSplit() 用于拆分字符串

absl::StrSplit()函数提供了一种将字符串拆分为子字符串的简单方法。StrSplit()接受要分割的输入字符串、分割字符串的定界符(例如逗号,)和(可选)作为过滤器的谓词,以判断是否将分割元素包含在结果集中。 StrSplit()还将返回的集合调整为调用者指定的类型。

例子:

// Splits the given string on commas. Returns the results in a
// vector of strings. (Data is copied once.)
std::vector<std::string> v = absl::StrSplit("a,b,c", ',');  // Can also use ","
// v[0] == "a", v[1] == "b", v[2] == "c"

// Splits the string as in the previous example, except that the results
// are returned as `absl::string_view` objects, avoiding copies. Note that
// because we are storing the results within `absl::string_view` objects, we
// have to ensure that the input string outlives any results.
std::vector<absl::string_view> v = absl::StrSplit("a,b,c", ',');
// v[0] == "a", v[1] == "b", v[2] == "c"

StrSplit()使用传递的Delimiter对象拆分字符串。(请参阅 下面的分隔符。)但是,在许多情况下,您可以简单地将字符串文字作为分隔符传递(它将被隐式转换为 absl::ByString分隔符)。

例子:

// By default, empty strings are *included* in the output. See the
// `absl::SkipEmpty()` predicate below to omit them{#stringSplitting}.
std::vector<std::string> v = absl::StrSplit("a,b,,c", ',');
// v[0] == "a", v[1] == "b", v[2] == "", v[3] = "c"

// You can also split an empty string
v = absl::StrSplit("", ',');
// v[0] = ""

// The delimiter need not be a single character
std::vector<std::string> v = absl::StrSplit("aCOMMAbCOMMAc", "COMMA");
// v[0] == "a", v[1] == "b", v[2] == "c"

// You can also use the empty string as the delimiter, which will split
// a string into its constituent characters.
std::vector<std::string> v = absl::StrSplit("abcd", "");
// v[0] == "a", v[1] == "b", v[2] == "c", v[3] = "d"

适应返回类型

StrSplit()API更有用的特性之一是它能够将其结果集调整为所需的返回类型。StrSplit()返回的集合可能包含std::stringabsl::string_view或任何可以从absl::string_view. 这种模式适用于所有的标准STL容器,包括std::vectorstd::liststd::dequestd::set, std::multisetstd::map,和std::multimap,甚至std::pair,这是不实际的容器。

例子:

// Stores results in a std::set<std::string>, which also performs de-duplication
// and orders the elements in ascending order.
std::set<std::string> s = absl::StrSplit("b,a,c,a,b", ',');
// s[0] == "a", s[1] == "b", s[3] == "c"

// Stores results in a map. The map implementation assumes that the input
// is provided as a series of key/value pairs. For example, the 0th element
// resulting from the split will be stored as a key to the 1st element. If
// an odd number of elements are resolved, the last element is paired with
// a default-constructed value (e.g., empty string).
std::map<std::string, std::string> m = absl::StrSplit("a,b,c", ',');
// m["a"] == "b", m["c"] == "" // last component value equals ""

// Stores first two split strings as the members in a std::pair. Any split
// strings beyond the first two are omitted because std::pair can hold only two
// elements.
std::pair<std::string, std::string> p = absl::StrSplit("a,b,c", ',');
// p.first = "a", p.second = "b" ; "c" is omitted

分隔符

StrSplit()API提供了许多“分隔符”,用于提供特殊的分隔符的行为。Delimiter 实现包含一个Find()函数,该函数知道如何在给定的absl::string_view. Delimiter 概念的模型表示特定类型的分隔符,例如单个字符、子字符串,甚至正则表达式。

以下 Delimiter 抽象作为StrSplit() API 的一部分提供:

  • absl::ByString()std::string参数的默认值)
  • absl::ByChar()char参数的默认值)
  • absl::ByAnyChar() (用于混合分隔符)
  • absl::ByLength() (用于应用定界符一定次数)
  • absl::MaxSplits() (用于拆分特定次数)

例子:

// Because a `string` literal is converted to an `absl::ByString`, the following
// two splits are equivalent.
std::vector<std::string> v = absl::StrSplit("a,b,c", ",");
std::vector<std::string> v = absl::StrSplit("a,b,c", absl::ByString(","));
// v[0] == "a", v[1] == "b", v[2] == "c"

// Because a `char` literal is converted to an `absl::ByChar`, the following two
// splits are equivalent.
std::vector<std::string> v = absl::StrSplit("a,b,c", ',');
// v[0] == "a", v[1] == "b", v[2] == "c"

std::vector<std::string> v = absl::StrSplit("a,b,c", absl::ByChar(','));
// v[0] == "a", v[1] == "b", v[2] == "c"

// Splits on any of the given characters ("," or ";")
vector<std::string> v = absl::StrSplit("a,b;c", absl::ByAnyChar(",;"));
// v[0] == "a", v[1] == "b", v[2] == "c"

// Uses the `absl::MaxSplits` delimiter to limit the number of matches a
// delimiter can have. In this case, the delimiter of a literal comma is limited
// to matching at most one time. The last element in the returned collection
// will contain all unsplit pieces, which may contain instances of the
// delimiter.
std::vector<std::string> v = absl::StrSplit("a,b,c", absl::MaxSplits(',', 1));
// v[0] == "a", v[1] == "b,c"

// Splits into equal-length substrings.
std::vector<std::string> v = absl::StrSplit("12345", absl::ByLength(2));
// v[0] == "12", v[1] == "34", v[2] == "5"

过滤谓词

谓词可以StrSplit()通过确定结果元素是否包含在结果集中来过滤操作的结果。过滤谓词可以作为可选的第三个参数传递给StrSplit() 函数。

谓词必须是一元函数(或函子),它们接受单个 absl::string_view参数并返回一个布尔值,指示该参数是应该被包含 ( true) 还是排除 ( false)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值