Samchon Framework for CPP  1.0.0
StringUtil.hpp
1 #pragma once
2 
3 #include <string>
4 #include <iostream>
5 #include <sstream>
6 
7 #include <samchon/WeakString.hpp>
8 #include <samchon/IndexPair.hpp>
9 #include <samchon/library/Math.hpp>
10 
11 namespace samchon
12 {
13 namespace library
14 {
36  class StringUtil
37  {
38  public:
39  /* ----------------------------------------------------------------------
40  SUBSTITUTE
41  ---------------------------------------------------------------------- */
53  template <typename T, typename ... _Args>
54  static auto substitute(const std::string &format,
55  const T& val, const _Args& ... args) -> std::string
56  {
57  std::string &res = _substitute(format, val);
58 
59  return StringUtil::substitute(res, args...);
60  };
61  template <typename T> static auto substitute(const std::string &format, const T& val) -> std::string
62  {
63  return _substitute(format, val);
64  };
65 
79  template <typename T, typename ... _Args >
80  static auto substituteSQL(const std::string &format,
81  const T& value, const _Args& ... args) -> std::string
82  {
83  std::string &res = _substituteSQL(format, value);
84  return StringUtil::substituteSQL(res, args...);
85  };
86  template <typename T> static auto substituteSQL(const std::string &format, const T& value) -> std::string
87  {
88  return _substituteSQL(format, value);
89  };
90 
91  protected:
92  template <typename T> static auto _substitute(const std::string &format, const T& value) -> std::string
93  {
94  std::vector<std::string> &parenthesisArray = betweens(format, { (char)'{' }, { (char)'}' });
95  std::vector<long> vec;
96 
97  for (auto it = parenthesisArray.begin(); it != parenthesisArray.end(); it++)
98  if (isNumeric(*it) == true)
99  vec.push_back(stoi(*it));
100 
101  size_t index = (size_t)Math::minimum(vec).getValue();
102 
103  //replaceAll
104  std::string &to = toString(value);
105  return replaceAll(format, "{" + std::to_string(index) + "}", to);
106  };
107 
108  template <typename T> static auto _substituteSQL(const std::string &format, const T& value) -> std::string
109  {
110  std::vector<std::string> &parenthesisArray = betweens(format, "{", "}");
111  std::vector<long> vec;
112 
113  for (auto it = parenthesisArray.begin(); it != parenthesisArray.end(); it++)
114  if (isNumeric(*it) == true)
115  vec.push_back(stoi(*it));
116 
117  size_t index = (size_t)Math::minimum(vec).getValue();
118 
119  //replaceAll
120  std::string &to = toSQL(value);
121  return replaceAll(format, "{" + std::to_string(index) + "}", to);
122  };
123 
124  /* ----------------------------------------------------------------------
125  SUBSTITUTE -> TO_STRING
126  ---------------------------------------------------------------------- */
127  template <typename T>
128  static auto toString(const T &val) -> std::string
129  {
130  return std::to_string(val);
131  };
132  template<> static auto toString(const std::string &str) -> std::string
133  {
134  return str;
135  };
136  template<> static auto toString(const WeakString &str) -> std::string
137  {
138  return str.str();
139  };
140  static auto toString(const char *ptr) -> std::string
141  {
142  return ptr;
143  };
144 
145  template <typename T>
146  static auto toSQL(const T &val) -> std::string
147  {
148  if (val == INT_MIN)
149  return "NULL";
150 
151  return std::to_string(val);
152  };
153  template<> static auto toSQL(const bool &flag) -> std::string
154  {
155  return std::to_string(flag);
156  };
157  template<> static auto toSQL(const char &val) -> std::string
158  {
159  return toSQL(std::string({ val }));
160  };
161  template<> static auto toSQL(const std::string &str) -> std::string
162  {
163  return toSQL(WeakString(str));
164  };
165  template<> static auto toSQL(const WeakString &wstr) -> std::string
166  {
167  if (wstr.empty() == true)
168  return "NULL";
169  else
170  {
171  if (wstr.find("'") != std::string::npos)
172  return "'" + wstr.replaceAll("'", "''") + "'";
173  else
174  return "'" + wstr.str() + "'";
175  }
176  };
177  static auto toSQL(const char *ptr) -> std::string
178  {
179  return toSQL(std::string(ptr));
180  };
181 
182  public:
183  /* ----------------------------------------------------------------------
184  NUMBER-FORMAT
185  IN MONETARY UNIT, ADD DELIMETER ','
186  COLOR-FORMAT
187 
188  POSITIVE NUMBER IS RED,
189  NEGATIVE NUMBER IS BLUE
190  ZERO IS BLACK
191  ---------------------------------------------------------------------- */
198  static auto isNumeric(const std::string &str) -> bool
199  {
200  try
201  {
202  stoi(str);
203  //stod( replaceAll(str, ",", "") );
204  }
205  catch (const std::exception &)
206  {
207  return false;
208  }
209  catch (...)
210  {
211  return false;
212  }
213 
214  return true;
215  };
216 
223  static auto toNumber(const std::string &str) -> double
224  {
225  std::string &numStr = replaceAll(str, ",", "");
226 
227  return stod(numStr);
228  };
229 
241  static auto numberFormat(double val, int precision = 2) -> std::string
242  {
243  std::string str;
244 
245  // FIRST, DO ROUND-OFF
246  val = round(val * pow(10, precision));
247  val = val / pow(10, precision);
248 
249  // SEPERATE NUMBERS
250  bool is_negative = (val < 0);
251  unsigned long long natural = (unsigned long long)abs(val);
252  double fraction = abs(val) - (unsigned long long)abs(val);
253 
254  // NATURAL NUMBER
255  if (natural == 0)
256  str = "0";
257  else
258  {
259  // NOT ZERO
260  size_t cipher_count = (size_t)log10(natural) + 1;
261 
262  for (size_t i = 0; i <= cipher_count; i++)
263  {
264  size_t cipher = natural % (size_t)pow(10, i + 1);
265  cipher = (size_t)(cipher / pow(10, i));
266 
267  if (i == cipher_count && cipher == 0)
268  continue;
269 
270  // IS MULTIPLIER OF 3
271  if (i > 0 && i % 3 == 0)
272  str = "," + str;
273 
274  // PUSH FRONT TO THE STRING
275  str = std::to_string(cipher) + str;
276  }
277  }
278 
279  // NEGATIVE SIGN
280  if (is_negative == true)
281  str = "-" + str;
282 
283  // ADD FRACTION
284  if (precision > 0 && fraction != 0)
285  {
286  fraction = (double)(unsigned long long)round(fraction * pow(10, precision));
287  size_t zeros = precision - (size_t)log10(fraction) - 1;
288 
289  str += "." + std::string(zeros, '0') + std::to_string((unsigned long long)fraction);
290  }
291  return str;
292  };
293 
303  static auto percentFormat(double val, int precision = 2) -> std::string
304  {
305  if (val == INT_MIN)
306  return "";
307  return numberFormat(val * 100, precision) + "%";
308  };
309 
325  static auto colorNumberFormat(double value, int precision = 2, double delimiter = 0.0) -> std::string
326  {
327  std::string color;
328 
329  if (value > delimiter) color = "red";
330  else if (value == delimiter) color = "black";
331  else color = "blue";
332 
333  return substitute
334  (
335  "<font color='{1}'>{2}</font>",
336  color,
337  numberFormat(value, precision)
338  );
339  };
340 
349  static auto colorPercentFormat(double value, int precision = 2, double delimiter = 0.0) -> std::string
350  {
351  std::string color;
352 
353  if (value > delimiter) color = "red";
354  else if (value == delimiter) color = "black";
355  else color = "blue";
356 
357  return substitute
358  (
359  "<font color='{1}'>{2}</font>",
360  color,
361  percentFormat(value, precision)
362  );
363  };
364 
365  /* ----------------------------------------------------------------------
366  TRIM -> WITH LTRIM & RTRIM
367  IT'S RIGHT, THE TRIM OF ORACLE
368  ---------------------------------------------------------------------- */
376  static auto trim(const std::string &val, const std::vector<std::string> &delims) -> std::string
377  {
378  return WeakString(val).trim(delims).str();
379  };
380 
388  static auto ltrim(const std::string &val, const std::vector<std::string> &delims) -> std::string
389  {
390  return WeakString(val).ltrim(delims).str();
391  };
392 
400  static auto rtrim(const std::string &val, const std::vector<std::string> &delims) -> std::string
401  {
402  return WeakString(val).rtrim(delims).str();
403  };
404 
405  static auto trim(const std::string &str) -> std::string
406  {
407  return WeakString(str).trim().str();
408  };
409  static auto ltrim(const std::string &str) -> std::string
410  {
411  return WeakString(str).ltrim().str();
412  };
413  static auto rtrim(const std::string &str) -> std::string
414  {
415  return WeakString(str).rtrim().str();
416  };
417 
418  static auto trim(const std::string &str, const std::string &delim) -> std::string
419  {
420  return WeakString(str).trim(delim).str();
421  };
422  static auto ltrim(const std::string &str, const std::string &delim) -> std::string
423  {
424  return WeakString(str).ltrim(delim).str();
425  };
426  static auto rtrim(const std::string &str, const std::string &delim) -> std::string
427  {
428  return WeakString(str).rtrim(delim).str();
429  };
430 
431  /* ----------------------------------------------------------------------
432  EXTRACTORS
433  ---------------------------------------------------------------------- */
449  static auto finds(const std::string &str,
450  const std::vector<std::string> &delims, size_t startIndex = 0) -> IndexPair<std::string>
451  {
452  IndexPair<WeakString> &iPair = WeakString(str).finds(delims, startIndex);
453 
454  return { iPair.get_index(), iPair.getValue().str() };
455  };
456 
472  static auto rfinds(const std::string &str,
473  const std::vector<std::string> &delims, size_t endIndex = SIZE_MAX) -> IndexPair<std::string>
474  {
475  IndexPair<WeakString> &iPair = WeakString(str).rfinds(delims, endIndex);
476 
477  return { iPair.get_index(), iPair.getValue().str() };
478  };
479 
495  static auto substring(const std::string &str,
496  size_t startIndex, size_t endIndex = SIZE_MAX) -> std::string
497  {
498  return WeakString(str).substring(startIndex, endIndex).str();
499  };
500 
520  static auto between(const std::string &str,
521  const std::string &start = "", const std::string &end = "") -> std::string
522  {
523  return WeakString(str).between(start, end).str();
524  };
525 
526  //TAB
534  static auto addTab(const std::string &str, size_t n = 1) -> std::string
535  {
536  std::vector<std::string> &lines = split(str, "\n");
537 
538  std::string val;
539  std::string tab;
540  size_t i;
541 
542  val.reserve(val.size() + lines.size());
543  tab.reserve(n);
544 
545  for (i = 0; i < n; i++)
546  tab += "\t";
547 
548  for (i = 0; i < lines.size(); i++)
549  val.append(tab + lines[i] + ((i == lines.size() - 1) ? "" : "\n"));
550 
551  return val;
552  };
553 
554  //MULTIPLE STRINGS
563  static auto split(const std::string &str, const std::string &delim) -> std::vector<std::string>
564  {
565  std::vector<WeakString> &arr = WeakString(str).split(delim);
566 
567  std::vector<std::string> resArray(arr.size());
568  for (size_t i = 0; i < arr.size(); i++)
569  resArray[i] = move(arr[i].str());
570 
571  return resArray;
572  };
573 
592  static auto betweens
593  (
594  const std::string &str,
595  const std::string &start = "", const std::string &end = ""
596  ) -> std::vector<std::string>
597  {
598  std::vector<WeakString> &arr = WeakString(str).betweens(start, end);
599 
600  std::vector<std::string> resArray(arr.size());
601  for (size_t i = 0; i < arr.size(); i++)
602  resArray[i] = move(arr[i].str());
603 
604  return resArray;
605  };
606 
607  /* ----------------------------------------------------------------------
608  REPLACERS
609  ---------------------------------------------------------------------- */
610  //ALPHABET-CONVERSION
617  static auto toLowerCase(const std::string &str) -> std::string
618  {
619  return WeakString(str).toLowerCase();
620  };
621 
628  static auto yoUpperCase(const std::string &str) -> std::string
629  {
630  return WeakString(str).yoUpperCase();
631  };
632 
641  static auto replaceAll
642  (
643  const std::string &str,
644  const std::string &before, const std::string &after
645  ) -> std::string
646  {
647  return WeakString(str).replaceAll(before, after);
648  };
649 
657  static auto replaceAll(const std::string &str,
658  const std::vector<std::pair<std::string, std::string>> &pairs) -> std::string
659  {
660  return WeakString(str).replaceAll(pairs);
661  };
662 
668  static auto removeHTMLSpaces(const std::string &str) -> std::string
669  {
670  std::vector<std::pair<std::string, std::string>> pairs =
671  {
672  { "&nbsp;", " " },
673  { "\t", " " },
674  { " ", " " }
675  };
676  return replaceAll(str, pairs);
677  };
678  };
679 };
680 };
static auto substituteSQL(const std::string &format, const T &value, const _Args &...args) -> std::string
Substitutes "{n}" tokens within the specified sql-string with the respective arguments passed in...
Definition: StringUtil.hpp:80
static auto percentFormat(double val, int precision=2) -> std::string
Returns a percentage string converted from the number rounded off from specified precision with "...
Definition: StringUtil.hpp:303
auto str() const -> std::string
Get the string content.
Definition: WeakString.hpp:926
static auto ltrim(const std::string &val, const std::vector< std::string > &delims) -> std::string
Removes all designated characters from the beginning of the specified string.
Definition: StringUtil.hpp:388
static auto substring(const std::string &str, size_t startIndex, size_t endIndex=SIZE_MAX) -> std::string
Generates a substring.
Definition: StringUtil.hpp:495
auto empty() const -> bool
Tests wheter string is emtpy.
Definition: WeakString.hpp:231
auto rfinds(const std::vector< std::string > &delims, size_t endIndex=SIZE_MAX) const -> IndexPair< WeakString >
Finds last occurence in string.
Definition: WeakString.hpp:366
static auto toNumber(const std::string &str) -> double
Number std::string to Number having &#39;,&#39; symbols.
Definition: StringUtil.hpp:223
static auto rfinds(const std::string &str, const std::vector< std::string > &delims, size_t endIndex=SIZE_MAX) -> IndexPair< std::string >
Finds last occurence in string.
Definition: StringUtil.hpp:472
auto getValue() -> T &
Get reference of value.
Definition: IndexPair.hpp:92
auto replaceAll(const WeakString &before, const WeakString &after) const -> std::string
Returns a string specified word is replaced.
Definition: WeakString.hpp:763
static auto addTab(const std::string &str, size_t n=1) -> std::string
Adds tab() character to first position of each line.
Definition: StringUtil.hpp:534
static auto colorPercentFormat(double value, int precision=2, double delimiter=0.0) -> std::string
Returns a percentage string converted from the number rounded off from specified precision with "...
Definition: StringUtil.hpp:349
auto toLowerCase() const -> std::string
Convert uppercase letters to lowercase.
Definition: WeakString.hpp:851
auto betweens(const WeakString &start={}, const WeakString &end={}) const -> std::vector< WeakString >
Generates substrings.
Definition: WeakString.hpp:548
static auto finds(const std::string &str, const std::vector< std::string > &delims, size_t startIndex=0) -> IndexPair< std::string >
Finds first occurence in string.
Definition: StringUtil.hpp:449
auto finds(const std::vector< std::string > &delims, size_t startIndex=0) const -> IndexPair< WeakString >
Finds first occurence in string.
Definition: WeakString.hpp:330
static auto replaceAll(const std::string &str, const std::vector< std::pair< std::string, std::string >> &pairs) -> std::string
Returns a string specified words are replaced.
Definition: StringUtil.hpp:657
static auto substitute(const std::string &format, const T &val, const _Args &...args) -> std::string
Substitutes "{n}" tokens within the specified string with the respective arguments passed in...
Definition: StringUtil.hpp:54
static auto split(const std::string &str, const std::string &delim) -> std::vector< std::string >
Generates substrings.
Definition: StringUtil.hpp:563
static auto minimum(const _Cont &container) -> IndexPair< T >
Calculate minimum value with its index.
Definition: Math.hpp:177
auto between(const WeakString &start={}, const WeakString &end={}) const -> WeakString
Generates a substring.
Definition: WeakString.hpp:475
static auto numberFormat(double val, int precision=2) -> std::string
Definition: StringUtil.hpp:241
auto substring(size_t startIndex, size_t endIndex=SIZE_MAX) const -> WeakString
Generates a substring.
Definition: WeakString.hpp:443
auto find(const WeakString &delim, size_t startIndex=NULL) const -> size_t
Finds first occurence in string.
Definition: WeakString.hpp:273
static auto rtrim(const std::string &val, const std::vector< std::string > &delims) -> std::string
Removes all designated characters from the end of the specified string.
Definition: StringUtil.hpp:400
A pair of index and its value(T)
Definition: IndexPair.hpp:30
static auto isNumeric(const std::string &str) -> bool
Returns wheter the std::string represents Number or not .
Definition: StringUtil.hpp:198
static auto colorNumberFormat(double value, int precision=2, double delimiter=0.0) -> std::string
Returns a string converted from the number rounded off from specified precision with "...
Definition: StringUtil.hpp:325
static auto betweens(const std::string &str, const std::string &start="", const std::string &end="") -> std::vector< std::string >
Generates substrings.
Definition: StringUtil.hpp:593
auto yoUpperCase() const -> std::string
Convert uppercase letters to lowercase.
Definition: WeakString.hpp:869
static auto replaceAll(const std::string &str, const std::string &before, const std::string &after) -> std::string
Returns a string specified word is replaced.
Definition: StringUtil.hpp:642
auto split(const WeakString &delim) const -> std::vector< WeakString >
Generates substrings.
Definition: WeakString.hpp:502
static auto between(const std::string &str, const std::string &start="", const std::string &end="") -> std::string
Generate a substring.
Definition: StringUtil.hpp:520
static auto trim(const std::string &val, const std::vector< std::string > &delims) -> std::string
Removes all designated characters from the beginning and end of the specified string.
Definition: StringUtil.hpp:376
auto get_index() const -> size_t
Get index.
Definition: IndexPair.hpp:82
A string class only references characeters, reference only.
Definition: WeakString.hpp:35
static auto removeHTMLSpaces(const std::string &str) -> std::string
Replace all HTML spaces to a literal space.
Definition: StringUtil.hpp:668
static auto toLowerCase(const std::string &str) -> std::string
Returns a string that all uppercase characters are converted to lowercase.
Definition: StringUtil.hpp:617
static auto yoUpperCase(const std::string &str) -> std::string
Definition: StringUtil.hpp:628
Utility class for string.
Definition: StringUtil.hpp:36