CppCommon  1.0.4.1
C++ Common Library
string_utils.cpp
Go to the documentation of this file.
1 
9 #include "string/string_utils.h"
10 
11 #include <cassert>
12 #include <regex>
13 
14 namespace CppCommon {
15 
16 bool 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 
25 bool 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 
37 bool 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 
62 std::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 
67 std::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 
72 std::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 
80 std::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 
86 std::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 
92 bool StringUtils::Compare(std::string_view str1, std::string_view str2)
93 {
94  return (str1 == str2);
95 }
96 
97 bool 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 
104 size_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 
118 bool 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 
128 bool 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 
138 bool 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 
153 std::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 
180 std::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 
207 std::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 
234 std::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 
248 std::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 
265 std::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 
282 std::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 
299 template <>
300 bool 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.
Definition: token_bucket.h:15
String utilities definition.