该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::string
、absl::string_view
或任何可以从absl::string_view
. 这种模式适用于所有的标准STL容器,包括std::vector
,std::list
,std::deque
,std::set
, std::multiset
,std::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
)。