GGS(GenericGEANT4Simulation)Software  2.6.0
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
GGSStringUtils.cpp
1 /*
2  * StringUtils.cpp
3  *
4  * Created on: 10 Oct 2018
5  * Author: Nicola Mori
6  */
7 
8 #include "utils/GGSStringUtils.h"
9 
10 #include <algorithm>
11 #include <stdexcept>
12 
13 Tokens GGSStringUtils::Tokenize(const std::string &str, char delimiter) {
14  Tokens tokens;
15 
16  size_t iChar = 0;
17  char endliteralDelimiter = '\0';
18  // Discard trailing spaces and tabs
19  while (str[iChar] == ' ' || str[iChar] == '\t')
20  iChar++;
21 
22  // Tokenize the string
23  std::string token;
24  tokens.clear();
25  while (iChar < str.size()) {
26 
27  size_t iLast = 0;
28  bool quotedText = false;
29  if (str[iChar] == '\"') {
30  quotedText = true;
31  endliteralDelimiter = '\"';
32  iChar++;
33  iLast = str.find_first_of('\"', iChar);
34  }
35  else if (str[iChar] == '{') {
36  quotedText = true;
37  endliteralDelimiter = '}';
38  iChar++;
39  iLast = str.find_first_of('}', iChar);
40  }
41  else {
42  iLast = str.find_first_of(delimiter, iChar + 1);
43  }
44  if (iLast != std::string::npos) {
45  // Delimiter character found
46  token = str.substr(iChar, iLast - iChar);
47  if (str[iLast] == endliteralDelimiter) {
48  iLast++;
49  quotedText = false;
50  }
51  }
52  else {
53  // Delimiter character not found.
54  if (quotedText) {
55  // Missing closing double quotation.
56  throw std::runtime_error(std::string("[GGSStringUtils::Tokenize] Missing closing ") + endliteralDelimiter);
57  }
58  else {
59  // Take all the characters up to the end of the string
60  token = str.substr(iChar);
61  }
62  }
63  tokens.push_back(token);
64 
65  iChar = str.find_first_not_of(delimiter, iLast);
66  }
67 
68  return tokens;
69 }
70 
71 std::string GGSStringUtils::Trim(const std::string &str) {
72  std::string retStr = str;
73  retStr.erase(retStr.begin(), std::find_if(retStr.begin(), retStr.end(), [](int ch) {
74  return !(std::isblank(static_cast<unsigned int>(ch)));
75  }));
76  retStr.erase(std::find_if(retStr.rbegin(), retStr.rend(), [](int ch) {
77  return !(std::isblank(static_cast<unsigned int>(ch)));
78  }).base(), retStr.end());
79  return retStr;
80 }
81 
82 bool GGSStringUtils::IsInteger(const std::string &str) {
83  std::string trimmedStr = Trim(str);
84  if (trimmedStr.empty() || ((!isdigit(trimmedStr[0])) && (trimmedStr[0] != '-') && (trimmedStr[0] != '+')))
85  return false;
86  for (unsigned int iChar = 1; iChar < trimmedStr.size(); iChar++) {
87  if (!isdigit(trimmedStr[iChar])) {
88  return false;
89  }
90  }
91  return true;
92 }
93 
94 bool GGSStringUtils::IsReal(const std::string &str) {
95  std::string trimmedStr = Trim(str);
96  if (trimmedStr.empty() || ((!isdigit(trimmedStr[0])) && (trimmedStr[0] != '-') && (trimmedStr[0] != '+')))
97  return false;
98  bool hasPoint = false;
99  bool hase = false;
100  for (unsigned int iChar = 1; iChar < trimmedStr.size(); iChar++) {
101  if (!isdigit(trimmedStr[iChar])) {
102  if (trimmedStr[iChar] == '.') {
103  if (hasPoint) {
104  return false;
105  }
106  hasPoint = true;
107  }
108  else if (trimmedStr[iChar] == 'e') {
109  if (hase) {
110  return false;
111  }
112  hase = true;
113  // After 'e' there must be a digit or a sign
114  ++iChar;
115  if (iChar >= trimmedStr.size()
116  || (!isdigit(trimmedStr[iChar]) && (trimmedStr[iChar] != '-') && (trimmedStr[iChar] != '+'))) {
117  return false;
118  }
119  }
120  else {
121  return false;
122  }
123  }
124  }
125  return true;
126 }
127 
128 bool GGSStringUtils::IsGlobExpression(const std::string &str) {
129  if (str.find('*') != std::string::npos || str.find('?') != std::string::npos) {
130  return true;
131  }
132  else {
133  return false;
134  }
135 }
136 
137 std::string GGSStringUtils::RegexFromGlob(const std::string &str) {
138  static std::string regexStr;
139  regexStr = str;
140  std::string::size_type n = 0;
141  while ((n = regexStr.find(".", n)) != std::string::npos) {
142  regexStr.replace(n, 1, "\\.");
143  n += 2;
144  }
145  n = 0;
146  while ((n = regexStr.find("*", n)) != std::string::npos) {
147  regexStr.replace(n, 1, ".*");
148  n += 2;
149  }
150  std::replace(regexStr.begin(), regexStr.end(), '?', '.');
151  return regexStr;
152 }
153 
std::string RegexFromGlob(const std::string &str)
Build a regex starting from a glob expression.
Tokens Tokenize(const std::string &str, char delimiter= ' ')
Extracts words from a string.
bool IsGlobExpression(const std::string &str)
Check if the given string is a glob expression.
bool IsInteger(const std::string &str)
Checks if a string is an a integer.
bool IsReal(const std::string &str)
Checks if a string is a real number.
std::string Trim(const std::string &str)
Trims a string.