CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
string_utils.cpp
Go to the documentation of this file.
1
10
11#include <cassert>
12#include <regex>
13
14namespace CppCommon {
15
16bool StringUtils::IsBlank(const char* str)
17{
18 for (size_t i = 0; str[i] != 0; ++i)
19 if (!IsBlank(str[i]))
20 return false;
21
22 return true;
23}
24
25bool StringUtils::IsBlank(std::string_view str)
26{
27 if (str.empty())
28 return true;
29
30 for (auto ch : str)
31 if (!IsBlank(ch))
32 return false;
33
34 return true;
35}
36
37bool StringUtils::IsPatternMatch(const std::string& patterns, const std::string& str)
38{
39 bool result = false;
40 auto keys = Split(patterns, ';');
41 for (const std::string& key : keys)
42 {
43 bool negative = StartsWith(key, "!");
44 std::string pattern = negative ? key.substr(1) : key;
45
46 // Try to match regex pattern
47 try
48 {
49 std::regex expression(pattern);
50 bool matched = std::regex_match(str, expression);
51 if (matched)
52 return !negative;
53 }
54 catch (const std::regex_error&) {}
55
56 // Last negative pattern should success result
57 result = negative;
58 }
59 return result;
60}
61
62std::string StringUtils::ToLTrim(std::string_view str)
63{
64 return std::string(std::find_if(str.begin(), str.end(), [](int c) { return !std::isspace(c); }), str.end());
65}
66
67std::string StringUtils::ToRTrim(std::string_view str)
68{
69 return std::string(str.begin(), std::find_if(str.rbegin(), str.rend(), [](int c) { return !std::isspace(c); }).base());
70}
71
72std::string StringUtils::ToTrim(std::string_view str)
73{
74 auto start = std::find_if(str.begin(), str.end(), [](int c) { return !std::isspace(c); });
75 auto end = std::find_if(str.rbegin(), str.rend(), [](int c) { return !std::isspace(c); }).base();
76
77 return (start != str.end()) ? std::string(start, end) : std::string();
78}
79
80std::string& StringUtils::LTrim(std::string& str)
81{
82 str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](int c) { return !std::isspace(c); }));
83 return str;
84}
85
86std::string& StringUtils::RTrim(std::string& str)
87{
88 str.erase(std::find_if(str.rbegin(), str.rend(), [](int c) { return !std::isspace(c); }).base(), str.end());
89 return str;
90}
91
92bool StringUtils::Compare(std::string_view str1, std::string_view str2)
93{
94 return (str1 == str2);
95}
96
97bool StringUtils::CompareNoCase(std::string_view str1, std::string_view str2)
98{
99 if (str1.size() != str2.size())
100 return false;
101 return std::equal(str1.cbegin(), str1.cend(), str2.cbegin(), [](std::string::value_type l, std::string::value_type r) { return std::tolower(l) == std::tolower(r); });
102}
103
104size_t StringUtils::CountAll(std::string_view str, std::string_view substr)
105{
106 size_t count=0;
107
108 size_t pos = 0;
109 while ((pos = str.find(substr, pos)) != std::string::npos)
110 {
111 pos += substr.size();
112 ++count;
113 }
114
115 return count;
116}
117
118bool StringUtils::ReplaceFirst(std::string& str, std::string_view substr, std::string_view with)
119{
120 size_t pos = str.find(substr);
121 if (pos == std::string::npos)
122 return false;
123
124 str.replace(pos, substr.size(), with);
125 return true;
126}
127
128bool StringUtils::ReplaceLast(std::string& str, std::string_view substr, std::string_view with)
129{
130 size_t pos = str.rfind(substr);
131 if (pos == std::string::npos)
132 return false;
133
134 str.replace(pos, substr.size(), with);
135 return true;
136}
137
138bool StringUtils::ReplaceAll(std::string& str, std::string_view substr, std::string_view with)
139{
140 bool result = false;
141
142 size_t pos = 0;
143 while ((pos = str.find(substr, pos)) != std::string::npos)
144 {
145 str.replace(pos, substr.size(), with);
146 pos += with.size();
147 result = true;
148 }
149
150 return result;
151}
152
153std::vector<std::string> StringUtils::Split(std::string_view str, char delimiter, bool skip_empty)
154{
155 std::vector<std::string> tokens;
156
157 size_t pos_current;
158 size_t pos_last = 0;
159 size_t length;
160
161 while (true)
162 {
163 pos_current = str.find(delimiter, pos_last);
164 if (pos_current == std::string::npos)
165 pos_current = str.size();
166
167 length = pos_current - pos_last;
168 if (!skip_empty || (length != 0))
169 tokens.emplace_back(str.substr(pos_last, length));
170
171 if (pos_current == str.size())
172 break;
173 else
174 pos_last = pos_current + 1;
175 }
176
177 return tokens;
178}
179
180std::vector<std::string> StringUtils::Split(std::string_view str, std::string_view delimiter, bool skip_empty)
181{
182 std::vector<std::string> tokens;
183
184 size_t pos_current;
185 size_t pos_last = 0;
186 size_t length;
187
188 while (true)
189 {
190 pos_current = str.find(delimiter, pos_last);
191 if (pos_current == std::string::npos)
192 pos_current = str.size();
193
194 length = pos_current - pos_last;
195 if (!skip_empty || (length != 0))
196 tokens.emplace_back(str.substr(pos_last, length));
197
198 if (pos_current == str.size())
199 break;
200 else
201 pos_last = pos_current + delimiter.size();
202 }
203
204 return tokens;
205}
206
207std::vector<std::string> StringUtils::SplitByAny(std::string_view str, std::string_view delimiters, bool skip_empty)
208{
209 std::vector<std::string> tokens;
210
211 size_t pos_current;
212 size_t pos_last = 0;
213 size_t length;
214
215 while (true)
216 {
217 pos_current = str.find_first_of(delimiters, pos_last);
218 if (pos_current == std::string::npos)
219 pos_current = str.size();
220
221 length = pos_current - pos_last;
222 if (!skip_empty || (length != 0))
223 tokens.emplace_back(str.substr(pos_last, length));
224
225 if (pos_current == str.size())
226 break;
227 else
228 pos_last = pos_current + 1;
229 }
230
231 return tokens;
232}
233
234std::string StringUtils::Join(const std::vector<std::string>& tokens, bool skip_empty, bool skip_blank)
235{
236 if (tokens.empty())
237 return "";
238
239 std::ostringstream result;
240
241 for (size_t i = 0; i < tokens.size(); ++i)
242 if (!((skip_empty && tokens[i].empty()) || (skip_blank && IsBlank(tokens[i]))))
243 result << tokens[i];
244
245 return result.str();
246}
247
248std::string StringUtils::Join(const std::vector<std::string>& tokens, char delimiter, bool skip_empty, bool skip_blank)
249{
250 if (tokens.empty())
251 return "";
252
253 std::ostringstream result;
254
255 for (size_t i = 0; i < tokens.size() - 1; ++i)
256 if (!((skip_empty && tokens[i].empty()) || (skip_blank && IsBlank(tokens[i]))))
257 result << tokens[i] << delimiter;
258
259 if (!((skip_empty && tokens[tokens.size() - 1].empty()) || (skip_blank && IsBlank(tokens[tokens.size() - 1]))))
260 result << tokens[tokens.size() - 1];
261
262 return result.str();
263}
264
265std::string StringUtils::Join(const std::vector<std::string>& tokens, const char* delimiter, bool skip_empty, bool skip_blank)
266{
267 if (tokens.empty())
268 return "";
269
270 std::ostringstream result;
271
272 for (size_t i = 0; i < tokens.size() - 1; ++i)
273 if (!((skip_empty && tokens[i].empty()) || (skip_blank && IsBlank(tokens[i]))))
274 result << tokens[i] << delimiter;
275
276 if (!((skip_empty && tokens[tokens.size() - 1].empty()) || (skip_blank && IsBlank(tokens[tokens.size() - 1]))))
277 result << tokens[tokens.size() - 1];
278
279 return result.str();
280}
281
282std::string StringUtils::Join(const std::vector<std::string>& tokens, std::string_view delimiter, bool skip_empty, bool skip_blank)
283{
284 if (tokens.empty())
285 return "";
286
287 std::ostringstream result;
288
289 for (size_t i = 0; i < tokens.size() - 1; ++i)
290 if (!((skip_empty && tokens[i].empty()) || (skip_blank && IsBlank(tokens[i]))))
291 result << tokens[i] << delimiter;
292
293 if (!((skip_empty && tokens[tokens.size() - 1].empty()) || (skip_blank && IsBlank(tokens[tokens.size() - 1]))))
294 result << tokens[tokens.size() - 1];
295
296 return result.str();
297}
298
299template <>
300bool StringUtils::FromString(std::string_view str)
301{
302 std::string value = ToLower(str);
303 if ((value == "true") || (value == "yes") || (value == "on") || (value == "1"))
304 return true;
305 if ((value == "false") || (value == "no") || (value == "off") || (value == "0"))
306 return false;
307
308 assert("Invalid boolean value represented in string!");
309 return false;
310}
311
312} // namespace CppCommon
static bool Compare(std::string_view str1, std::string_view str2)
Compare two strings case sensitive version.
static std::vector< std::string > SplitByAny(std::string_view str, std::string_view delimiters, bool skip_empty=false)
Split the string into tokens by the any character in the given delimiter string.
static size_t CountAll(std::string_view str, std::string_view substr)
Count all occurrences of substring.
static std::vector< std::string > Split(std::string_view str, char delimiter, bool skip_empty=false)
Split the string into tokens by the given delimiter character.
static std::string ToRTrim(std::string_view str)
Trims space characters from the end of the given constant string.
static bool StartsWith(std::string_view str, std::string_view prefix)
Checks the given string for specific prefix.
static std::string & LTrim(std::string &str)
Trims space characters from the start of the given string.
static T FromString(std::string_view str)
Converts strings to arbitrary datatypes using std::istringstream.
static bool ReplaceAll(std::string &str, std::string_view substr, std::string_view with)
Replace all occurrences of substring with another substring.
static std::string ToLTrim(std::string_view str)
Trims space characters from the start of the given constant string.
static std::string Join(const std::vector< std::string > &tokens, bool skip_empty=false, bool skip_blank=false)
Join tokens into the string.
static char ToLower(char ch)
Convert the given character to lower case.
static bool ReplaceFirst(std::string &str, std::string_view substr, std::string_view with)
Replace the first occurrence of substring with another substring.
static std::string & RTrim(std::string &str)
Trims space characters from the end of the given string.
static bool CompareNoCase(std::string_view str1, std::string_view str2)
Compare two strings case insensitive version.
static std::string ToTrim(std::string_view str)
Trims space characters from the both sides of the given constant string.
static bool IsBlank(char ch)
Is the given character blank (empty or contains only space characters)?
static bool ReplaceLast(std::string &str, std::string_view substr, std::string_view with)
Replace the last occurrence of substring with another substring.
static bool IsPatternMatch(const std::string &patterns, const std::string &str)
Is the given string match to the given patterns?
C++ Common project definitions.
String utilities definition.