1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_STRINGS_STRING_SPLIT_H_
6 #define BASE_STRINGS_STRING_SPLIT_H_
7 
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/base_export.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/string_piece.h"
15 #include "build/build_config.h"
16 
17 namespace base {
18 
19 enum WhitespaceHandling {
20   KEEP_WHITESPACE,
21   TRIM_WHITESPACE,
22 };
23 
24 enum SplitResult {
25   // Strictly return all results.
26   //
27   // If the input is ",," and the separator is ',' this will return a
28   // vector of three empty strings.
29   SPLIT_WANT_ALL,
30 
31   // Only nonempty results will be added to the results. Multiple separators
32   // will be coalesced. Separators at the beginning and end of the input will
33   // be ignored. With TRIM_WHITESPACE, whitespace-only results will be dropped.
34   //
35   // If the input is ",," and the separator is ',', this will return an empty
36   // vector.
37   SPLIT_WANT_NONEMPTY,
38 };
39 
40 // Split the given string on ANY of the given separators, returning copies of
41 // the result.
42 //
43 // Note this is inverse of JoinString() defined in string_util.h.
44 //
45 // To split on either commas or semicolons, keeping all whitespace:
46 //
47 //   std::vector<std::string> tokens = base::SplitString(
48 //       input, ", WARN_UNUSED_RESULT;", base::KEEP_WHITESPACE,
49 //       base::SPLIT_WANT_ALL) WARN_UNUSED_RESULT;
50 BASE_EXPORT std::vector<std::string> SplitString(StringPiece input,
51                                                  StringPiece separators,
52                                                  WhitespaceHandling whitespace,
53                                                  SplitResult result_type)
54     WARN_UNUSED_RESULT;
55 BASE_EXPORT std::vector<string16> SplitString(StringPiece16 input,
56                                               StringPiece16 separators,
57                                               WhitespaceHandling whitespace,
58                                               SplitResult result_type)
59     WARN_UNUSED_RESULT;
60 
61 // Like SplitString above except it returns a vector of StringPieces which
62 // reference the original buffer without copying. Although you have to be
63 // careful to keep the original string unmodified, this provides an efficient
64 // way to iterate through tokens in a string.
65 //
66 // Note this is inverse of JoinString() defined in string_util.h.
67 //
68 // To iterate through all whitespace-separated tokens in an input string:
69 //
70 //   for (const auto& cur :
71 //        base::SplitStringPiece(input, base::kWhitespaceASCII,
72 //                               base::KEEP_WHITESPACE,
73 //                               base::SPLIT_WANT_NONEMPTY)) {
74 //     ...
75 BASE_EXPORT std::vector<StringPiece> SplitStringPiece(
76     StringPiece input,
77     StringPiece separators,
78     WhitespaceHandling whitespace,
79     SplitResult result_type) WARN_UNUSED_RESULT;
80 BASE_EXPORT std::vector<StringPiece16> SplitStringPiece(
81     StringPiece16 input,
82     StringPiece16 separators,
83     WhitespaceHandling whitespace,
84     SplitResult result_type) WARN_UNUSED_RESULT;
85 
86 using StringPairs = std::vector<std::pair<std::string, std::string>>;
87 
88 // Splits |line| into key value pairs according to the given delimiters and
89 // removes whitespace leading each key and trailing each value. Returns true
90 // only if each pair has a non-empty key and value. |key_value_pairs| will
91 // include ("","") pairs for entries without |key_value_delimiter|.
92 BASE_EXPORT bool SplitStringIntoKeyValuePairs(StringPiece input,
93                                               char key_value_delimiter,
94                                               char key_value_pair_delimiter,
95                                               StringPairs* key_value_pairs);
96 
97 // Similar to SplitStringIntoKeyValuePairs, but use a substring
98 // |key_value_pair_delimiter| instead of a single char.
99 BASE_EXPORT bool SplitStringIntoKeyValuePairsUsingSubstr(
100     StringPiece input,
101     char key_value_delimiter,
102     StringPiece key_value_pair_delimiter,
103     StringPairs* key_value_pairs);
104 
105 // Similar to SplitString, but use a substring delimiter instead of a list of
106 // characters that are all possible delimiters.
107 BASE_EXPORT std::vector<string16> SplitStringUsingSubstr(
108     StringPiece16 input,
109     StringPiece16 delimiter,
110     WhitespaceHandling whitespace,
111     SplitResult result_type) WARN_UNUSED_RESULT;
112 BASE_EXPORT std::vector<std::string> SplitStringUsingSubstr(
113     StringPiece input,
114     StringPiece delimiter,
115     WhitespaceHandling whitespace,
116     SplitResult result_type) WARN_UNUSED_RESULT;
117 
118 // Like SplitStringUsingSubstr above except it returns a vector of StringPieces
119 // which reference the original buffer without copying. Although you have to be
120 // careful to keep the original string unmodified, this provides an efficient
121 // way to iterate through tokens in a string.
122 //
123 // To iterate through all newline-separated tokens in an input string:
124 //
125 //   for (const auto& cur :
126 //        base::SplitStringUsingSubstr(input, "\r\n",
127 //                                     base::KEEP_WHITESPACE,
128 //                                     base::SPLIT_WANT_NONEMPTY)) {
129 //     ...
130 BASE_EXPORT std::vector<StringPiece16> SplitStringPieceUsingSubstr(
131     StringPiece16 input,
132     StringPiece16 delimiter,
133     WhitespaceHandling whitespace,
134     SplitResult result_type) WARN_UNUSED_RESULT;
135 BASE_EXPORT std::vector<StringPiece> SplitStringPieceUsingSubstr(
136     StringPiece input,
137     StringPiece delimiter,
138     WhitespaceHandling whitespace,
139     SplitResult result_type) WARN_UNUSED_RESULT;
140 
141 #if defined(OS_WIN) && defined(BASE_STRING16_IS_STD_U16STRING)
142 BASE_EXPORT std::vector<std::wstring> SplitString(WStringPiece input,
143                                                   WStringPiece separators,
144                                                   WhitespaceHandling whitespace,
145                                                   SplitResult result_type)
146     WARN_UNUSED_RESULT;
147 
148 BASE_EXPORT std::vector<WStringPiece> SplitStringPiece(
149     WStringPiece input,
150     WStringPiece separators,
151     WhitespaceHandling whitespace,
152     SplitResult result_type) WARN_UNUSED_RESULT;
153 
154 BASE_EXPORT std::vector<std::wstring> SplitStringUsingSubstr(
155     WStringPiece input,
156     WStringPiece delimiter,
157     WhitespaceHandling whitespace,
158     SplitResult result_type) WARN_UNUSED_RESULT;
159 
160 BASE_EXPORT std::vector<WStringPiece> SplitStringPieceUsingSubstr(
161     WStringPiece input,
162     WStringPiece delimiter,
163     WhitespaceHandling whitespace,
164     SplitResult result_type) WARN_UNUSED_RESULT;
165 #endif
166 
167 }  // namespace base
168 
169 #endif  // BASE_STRINGS_STRING_SPLIT_H_
170