swift
stringutils.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include "misc/stringutils.h"
7 
8 #include <QChar>
9 #include <QRegularExpression>
10 #include <QStringBuilder>
11 #include <QTextCodec>
12 
13 namespace swift::misc
14 {
15  QString removeDateTimeSeparators(const QString &s)
16  {
17  return removeChars(s, [](QChar c) { return c == u' ' || c == u':' || c == u'_' || c == u'-' || c == u'.'; });
18  }
19 
20  QList<QStringRef> splitLinesRefs(const QString &s)
21  {
22  return splitStringRefs(s, [](QChar c) { return c == '\n' || c == '\r'; });
23  }
24 
25  QStringList splitLines(const QString &s)
26  {
27  return splitString(s, [](QChar c) { return c == '\n' || c == '\r'; });
28  }
29 
30  QByteArray utfToPercentEncoding(const QString &s, const QByteArray &allow, char percent)
31  {
32  QByteArray result;
33  for (const QChar &c : s)
34  {
35  if (const char latin = c.toLatin1())
36  {
37  if ((latin >= 'a' && latin <= 'z') || (latin >= 'A' && latin <= 'Z') ||
38  (latin >= '0' && latin <= '9') || allow.contains(latin))
39  {
40  result += c.toLatin1();
41  }
42  else
43  {
44  result += percent;
45  if (latin < 0x10) { result += '0'; }
46  result += QByteArray::number(static_cast<int>(latin), 16);
47  }
48  }
49  else
50  {
51  result += percent;
52  result += 'x';
53  const ushort unicode = c.unicode();
54  if (unicode < 0x0010) { result += '0'; }
55  if (unicode < 0x0100) { result += '0'; }
56  if (unicode < 0x1000) { result += '0'; }
57  result += QByteArray::number(unicode, 16);
58  }
59  }
60  return result;
61  }
62 
63  QString utfFromPercentEncoding(const QByteArray &ba, char percent)
64  {
65  QString result;
66  for (int i = 0; i < ba.size(); ++i)
67  {
68  if (ba[i] == percent)
69  {
70  ++i;
71  Q_ASSERT(i < ba.size());
72  if (ba[i] == 'x')
73  {
74  ++i;
75  Q_ASSERT(i < ba.size());
76  result += QChar(ba.mid(i, 4).toInt(nullptr, 16));
77  i += 3;
78  }
79  else
80  {
81  result += static_cast<char>(ba.mid(i, 2).toInt(nullptr, 16));
82  ++i;
83  }
84  }
85  else { result += ba[i]; }
86  }
87  return result;
88  }
89 
90  const QString &boolToOnOff(bool v)
91  {
92  static const QString on("on");
93  static const QString off("off");
94  return v ? on : off;
95  }
96 
97  const QString &boolToYesNo(bool v)
98  {
99  static const QString yes("yes");
100  static const QString no("no");
101  return v ? yes : no;
102  }
103 
104  const QString &boolToTrueFalse(bool v)
105  {
106  static const QString t("true");
107  static const QString f("false");
108  return v ? t : f;
109  }
110 
111  const QString &boolToEnabledDisabled(bool v)
112  {
113  static const QString e("enabled");
114  static const QString d("disabled");
115  return v ? e : d;
116  }
117 
118  const QString &boolToNullNotNull(bool isNull)
119  {
120  static const QString n("null");
121  static const QString nn("not null");
122  return isNull ? n : nn;
123  }
124 
125  bool stringToBool(const QString &string)
126  {
127  QString s(string.trimmed().toLower());
128  if (s.isEmpty()) { return false; }
129 
130  // 1 char values
131  const QChar c = s.at(0);
132  if (c == '1' || c == 't' || c == 'y' || c == 'x') { return true; }
133  if (c == '0' || c == 'f' || c == 'n' || c == '_') { return false; }
134 
135  if (c == 'e') { return true; } // enabled
136  if (c == 'd') { return false; } // disabled
137 
138  // full words
139  if (s == "on") { return true; }
140  return false;
141  }
142 
143  int fuzzyShortStringComparision(const QString &str1, const QString &str2, Qt::CaseSensitivity cs)
144  {
145  // same
146  if (cs == Qt::CaseInsensitive)
147  {
148  if (caseInsensitiveStringCompare(str1, str2)) { return 100; }
149  }
150  else if (str1 == str2) { return 100; }
151 
152  // one string is empty
153  if (str1.isEmpty() || str2.isEmpty()) { return 0; }
154 
155  // make sure aStr is not shorter
156  const QString aStr = str1.length() >= str2.length() ? str1 : str2;
157  const QString bStr = str1.length() >= str2.length() ? str2 : str1;
158 
159  // starts/ends with
160  const double s1 = aStr.length();
161  const double s2 = bStr.length();
162  if (aStr.endsWith(bStr, cs)) { return qRound(s1 / s2 * 100); }
163  if (aStr.startsWith(bStr, cs)) { return qRound(s1 / s2 * 100); }
164 
165  // contains
166  if (aStr.contains(bStr, cs)) { return qRound(s1 / s2 * 100); }
167 
168  // char by char
169  double points = 0;
170  for (int p = 0; p < aStr.length(); p++)
171  {
172  if (p < bStr.length() && aStr[p] == bStr[p])
173  {
174  points += 1.0;
175  continue;
176  }
177 
178  // char after
179  const int after = p + 1;
180  if (after < bStr.length() && aStr[p] == bStr[after])
181  {
182  points += 0.5;
183  continue;
184  }
185 
186  // char before
187  const int before = p - 1;
188  if (before >= 0 && before < bStr.length() && aStr[p] == bStr[before])
189  {
190  points += 0.5;
191  continue;
192  }
193  }
194  return qRound(points / s1 * 100);
195  }
196 
197  QString intToHex(int value, int digits)
198  {
199  QString hex(QString::number(value, 16).toUpper());
200  int l = hex.length();
201  if (l >= digits) { return hex.right(digits); }
202  int d = digits - l;
203  return QString(d, '0') + hex;
204  }
205 
206  QString stripDesignatorFromCompleterString(const QString &candidate)
207  {
208  const QString s(candidate.trimmed().toUpper());
209  if (s.isEmpty()) { return QString(); }
210  return s.contains(' ') ? s.left(s.indexOf(' ')) : s;
211  }
212 
213  QStringList simpleTextCodecNamesImpl()
214  {
215  QStringList codecs;
216  for (const QByteArray &ba : QTextCodec::availableCodecs())
217  {
218  const QString c(QString::fromLocal8Bit(ba));
219  codecs << c;
220  }
221  return codecs;
222  }
223 
224  QStringList mibTextCodecNamesImpl()
225  {
226  QStringList codecs;
227  for (int mib : QTextCodec::availableMibs())
228  {
229  const QByteArray ba(QTextCodec::codecForMib(mib)->name());
230  const QString c(QString::fromLocal8Bit(ba));
231  codecs << c;
232  }
233  return codecs;
234  }
235 
236  QStringList textCodecNames(bool simpleNames, bool mibNames)
237  {
238  static const QStringList simple(simpleTextCodecNamesImpl());
239  static const QStringList mib(mibTextCodecNamesImpl());
240  if (simpleNames && mibNames)
241  {
242  QStringList s(simple);
243  s.append(mib);
244  return s;
245  }
246  if (simpleNames) { return simple; }
247  if (mibNames) { return mib; }
248  return QStringList();
249  }
250 
251  // http://www.codegur.online/14009522/how-to-remove-accents-diacritic-marks-from-a-string-in-qt
252  // https://stackoverflow.com/questions/14009522/how-to-remove-accents-diacritic-marks-from-a-string-in-qt
253  // https://german.stackexchange.com/questions/4992/conversion-table-for-diacritics-e-g-%C3%BC-%E2%86%92-ue
254  QString simplifyAccents(const QString &candidate)
255  {
256  static const QString diacriticLetters =
257  QString::fromUtf8("ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ");
258  static const QStringList noDiacriticLetters(
259  { "S", "OE", "Z", "s", "oe", "z", "Y", "Y", "u", "A", "A", "A", "A", "A", "A", "AE", "C", "E",
260  "E", "E", "E", "I", "I", "I", "I", "D", "N", "O", "O", "O", "O", "O", "O", "U", "U", "U",
261  "U", "Y", "s", "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i",
262  "i", "o", "n", "o", "o", "o", "o", "o", "o", "u", "u", "u", "u", "y", "y" });
263 
264  QString output = "";
265  for (int i = 0; i < candidate.length(); i++)
266  {
267  const QChar c = candidate[i];
268  int dIndex = diacriticLetters.indexOf(c);
269  if (dIndex < 0) { output.append(c); }
270  else
271  {
272  const QString replacement = noDiacriticLetters[dIndex];
273  output.append(replacement);
274  }
275  }
276  return output;
277  }
278 
279  QString simplifyByDecomposition(const QString &s)
280  {
281  QString result;
282  // QChar c (NOT QChar &c), see
283  // https://discordapp.com/channels/539048679160676382/539925070550794240/686321311076581440
284  for (const QChar &c : s)
285  {
286  if (c.decompositionTag() == QChar::NoDecomposition) { result.push_back(c); }
287  else
288  {
289  for (const QChar &dc : c.decomposition())
290  {
291  if (!dc.isMark()) { result.push_back(dc); }
292  }
293  }
294  }
295  return result;
296  }
297 
298  bool caseInsensitiveStringCompare(const QString &c1, const QString &c2)
299  {
300  return c1.length() == c2.length() && c1.startsWith(c2, Qt::CaseInsensitive);
301  }
302 
303  QString simplifyNameForSearch(const QString &name)
304  {
305  return removeChars(name.toUpper(), [](QChar c) { return !c.isUpper(); });
306  }
307 
308  QDateTime fromStringUtc(const QString &dateTimeString, const QString &format)
309  {
310  if (dateTimeString.isEmpty() || format.isEmpty()) { return QDateTime(); }
311  QDateTime dt = QDateTime::fromString(dateTimeString, format);
312  if (!dt.isValid()) { return dt; }
313  dt.setOffsetFromUtc(0); // must only be applied to valid timestamps
314  return dt;
315  }
316 
317  QDateTime fromStringUtc(const QString &dateTimeString, Qt::DateFormat format)
318  {
319  if (dateTimeString.isEmpty()) { return QDateTime(); }
320  QDateTime dt = QDateTime::fromString(dateTimeString, format);
321  if (!dt.isValid()) { return dt; }
322  dt.setOffsetFromUtc(0); // must only be applied to valid timestamps
323  return dt;
324  }
325 
326  QDateTime fromStringUtc(const QString &dateTimeString, const QLocale &locale, QLocale::FormatType format)
327  {
328  if (dateTimeString.isEmpty()) { return QDateTime(); }
329  QDateTime dt = locale.toDateTime(dateTimeString, format);
330  if (!dt.isValid()) { return dt; }
331  dt.setOffsetFromUtc(0); // must only be applied to valid timestamps
332  return dt;
333  }
334 
335  QDateTime parseMultipleDateTimeFormats(const QString &dateTimeString)
336  {
337  if (dateTimeString.isEmpty()) { return QDateTime(); }
338  if (isDigitsOnlyString(dateTimeString))
339  {
340  // 2017 0301 124421 321
341  if (dateTimeString.length() == 17) { return fromStringUtc(dateTimeString, "yyyyMMddHHmmsszzz"); }
342  if (dateTimeString.length() == 14) { return fromStringUtc(dateTimeString, "yyyyMMddHHmmss"); }
343  if (dateTimeString.length() == 12) { return fromStringUtc(dateTimeString, "yyyyMMddHHmm"); }
344  if (dateTimeString.length() == 8) { return fromStringUtc(dateTimeString, "yyyyMMdd"); }
345  return QDateTime();
346  }
347 
348  // remove simple separators and check if digits only again
349  const QString simpleSeparatorsRemoved = removeDateTimeSeparators(dateTimeString);
350  if (isDigitsOnlyString(simpleSeparatorsRemoved))
351  {
352  return parseMultipleDateTimeFormats(simpleSeparatorsRemoved);
353  }
354 
355  // stupid trial and error
356  QDateTime ts = fromStringUtc(dateTimeString, Qt::ISODateWithMs);
357  if (ts.isValid()) return ts;
358 
359  ts = fromStringUtc(dateTimeString, Qt::ISODate);
360  if (ts.isValid()) return ts;
361 
362  ts = fromStringUtc(dateTimeString, Qt::TextDate);
363  if (ts.isValid()) return ts;
364 
365  ts = fromStringUtc(dateTimeString, QLocale(), QLocale::LongFormat);
366  if (ts.isValid()) return ts;
367 
368  ts = fromStringUtc(dateTimeString, QLocale(), QLocale::ShortFormat);
369  if (ts.isValid()) return ts;
370 
371  // SystemLocaleShortDate,
372  // SystemLocaleLongDate,
373  return QDateTime();
374  }
375 
376  QDateTime parseDateTimeStringOptimized(const QString &dateTimeString)
377  {
378  if (dateTimeString.length() < 8) { return QDateTime(); }
379 
380  // yyyyMMddHHmmsszzz
381  // 01234567890123456
382  int year(QStringView { dateTimeString }.left(4).toInt());
383  int month(QStringView { dateTimeString }.mid(4, 2).toInt());
384  int day(QStringView { dateTimeString }.mid(6, 2).toInt());
385  QDate date;
386  date.setDate(year, month, day);
387  QDateTime dt;
388  dt.setOffsetFromUtc(0);
389  dt.setDate(date);
390  if (dateTimeString.length() < 12) { return dt; }
391 
392  QTime t;
393  const int hour(QStringView { dateTimeString }.mid(8, 2).toInt());
394  const int minute(QStringView { dateTimeString }.mid(10, 2).toInt());
395  const int second(dateTimeString.length() < 14 ? 0 : QStringView { dateTimeString }.mid(12, 2).toInt());
396  const int ms(dateTimeString.length() < 17 ? 0 : QStringView { dateTimeString }.right(3).toInt());
397 
398  t.setHMS(hour, minute, second, ms);
399  dt.setTime(t);
400  return dt;
401  }
402 
403  QString dotToLocaleDecimalPoint(QString &input) { return input.replace('.', QLocale::system().decimalPoint()); }
404 
405  QString dotToLocaleDecimalPoint(const QString &input)
406  {
407  QString copy(input);
408  return copy.replace('.', QLocale::system().decimalPoint());
409  }
410 
411  bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs)
412  {
413  if (cs == Qt::CaseSensitive) { return c1 == c2; }
414  return caseInsensitiveStringCompare(c1, c2);
415  }
416 
417  QString inApostrophes(const QString &in, bool ignoreEmpty)
418  {
419  if (in.isEmpty()) { return ignoreEmpty ? QString() : QStringLiteral("''"); }
420  return u'\'' % in % u'\'';
421  }
422 
423  QString inQuotes(const QString &in, bool ignoreEmpty)
424  {
425  if (in.isEmpty()) { return ignoreEmpty ? QString() : QStringLiteral("\"\""); }
426  return u'"' % in % u'"';
427  }
428 
429  QString withQuestionMark(const QString &question)
430  {
431  if (question.endsWith("?")) { return question; }
432  return question % u'?';
433  }
434 
435  int nthIndexOf(const QString &string, QChar ch, int nth, Qt::CaseSensitivity cs)
436  {
437  if (nth < 1 || string.isEmpty() || nth > string.length()) { return -1; }
438 
439  int from = 0;
440  int ci = -1;
441  for (int t = 0; t < nth; ++t)
442  {
443  ci = string.indexOf(ch, from, cs);
444  if (ci < 0) { return -1; }
445  from = ci + 1;
446  if (from >= string.length()) { return -1; }
447  }
448  return ci;
449  }
450 
451  QString joinStringSet(const QSet<QString> &set, const QString &separator)
452  {
453  if (set.isEmpty()) { return {}; }
454  if (set.size() == 1) { return *set.begin(); }
455  return set.values().join(separator);
456  }
457 
458  QMap<QString, QString> parseIniValues(const QString &data)
459  {
461  QList<QStringRef> lines = splitLinesRefs(data);
462  for (const QStringRef &l : lines)
463  {
464  if (l.isEmpty()) { continue; }
465  const int i = l.indexOf("=");
466  if (i < 0 || i >= l.length() + 1) { continue; }
467 
468  const QString key = l.left(i).trimmed().toString();
469  const QString value = l.mid(i + 1).toString();
470  if (value.isEmpty()) { continue; }
471  map.insert(key, value);
472  }
473  return map;
474  }
475 
476  QString removeSurroundingApostrophes(const QString &in)
477  {
478  if (in.size() < 2) { return in; }
479  if (in.startsWith("'") && in.endsWith("'")) { return in.mid(1, in.length() - 2); }
480  return in;
481  }
482 
483  QString removeSurroundingQuotes(const QString &in)
484  {
485  if (in.size() < 2) { return in; }
486  if (in.startsWith("\"") && in.endsWith("\"")) { return in.mid(1, in.length() - 2); }
487  return in;
488  }
489 
490  QString removeComments(const QString &in, bool removeSlashStar, bool removeDoubleSlash)
491  {
492  QString copy(in);
493 
494  thread_local const QRegularExpression re1("\\/\\*(.|\\n)*?\\*\\/");
495  if (removeSlashStar) { copy.remove(re1); }
496 
497  thread_local const QRegularExpression re2("\\/\\/.*");
498  if (removeDoubleSlash) { copy.remove(re2); }
499 
500  return copy;
501  }
502 
503  const QString &defaultIfEmpty(const QString &candidate, const QString &defaultIfEmpty)
504  {
505  if (candidate.isEmpty()) { return defaultIfEmpty; }
506  return candidate;
507  }
508 
509  bool containsAny(const QString &testString, const QStringList &any, Qt::CaseSensitivity cs)
510  {
511  if (testString.isEmpty() || any.isEmpty()) { return false; }
512  for (const QString &a : any)
513  {
514  if (testString.contains(a, cs)) { return true; }
515  }
516  return false;
517  }
518 
519  bool hasBalancedQuotes(const QString &in, char quote)
520  {
521  if (in.isEmpty()) { return true; }
522  const int c = in.count(quote);
523  return (c % 2) == 0;
524  }
525 
526  double parseFraction(const QString &fraction, double failDefault)
527  {
528  if (fraction.isEmpty()) { return failDefault; }
529  bool ok;
530 
531  double r = failDefault;
532  if (fraction.contains('/'))
533  {
534  const QStringList parts = fraction.split('/');
535  if (parts.size() != 2) { return failDefault; }
536  const double c = parts.front().trimmed().toDouble(&ok);
537  if (!ok) { return failDefault; }
538 
539  const double d = parts.last().trimmed().toDouble(&ok);
540  if (!ok) { return failDefault; }
541  if (qFuzzyCompare(0.0, d)) { return failDefault; }
542  r = c / d;
543  }
544  else
545  {
546  r = fraction.trimmed().toDouble(&ok);
547  if (!ok) { return failDefault; }
548  }
549  return r;
550  }
551 
552  QString cleanNumber(const QString &number)
553  {
554  QString n = number.trimmed();
555  if (n.isEmpty()) { return QString(); }
556 
557  int dp = n.indexOf('.');
558  if (dp < 0) { dp = n.indexOf(','); }
559 
560  // clean all trailing stuff
561  while (dp >= 0 && !n.isEmpty())
562  {
563  const QChar l = n.at(n.size() - 1);
564  if (l == '0')
565  {
566  n.chop(1);
567  continue;
568  }
569  else if (l == '.' || l == ',') { n.chop(1); }
570  break;
571  }
572 
573  while (n.startsWith("00")) { n.remove(0, 1); }
574 
575  return n;
576  }
577 
578 } // namespace swift::misc
579 
Free functions in swift::misc.
SWIFT_MISC_EXPORT QString withQuestionMark(const QString &question)
Add a question mark at the end if not existing.
SWIFT_MISC_EXPORT QString simplifyNameForSearch(const QString &name)
Get a simplified upper case name for searching by removing all characters except A-Z.
SWIFT_MISC_EXPORT QString cleanNumber(const QString &number)
Remove leading 0, trailing 0, " ", and "." from a number.
SWIFT_MISC_EXPORT QString inApostrophes(const QString &in, bool ignoreEmpty=false)
Return string in apostrophes.
SWIFT_MISC_EXPORT QString intToHex(int value, int digits=2)
Int to hex value.
SWIFT_MISC_EXPORT QByteArray utfToPercentEncoding(const QString &s, const QByteArray &allow={}, char percent='%')
Extended percent encoding supporting UTF-16.
SWIFT_MISC_EXPORT QString stripDesignatorFromCompleterString(const QString &candidate)
Strip a designator from a combined string.
SWIFT_MISC_EXPORT QDateTime parseMultipleDateTimeFormats(const QString &dateTimeString)
Parse multiple date time formats.
SWIFT_MISC_EXPORT QString utfFromPercentEncoding(const QByteArray &ba, char percent='%')
Reverse utfFromPercentEncoding.
SWIFT_MISC_EXPORT int fuzzyShortStringComparision(const QString &str1, const QString &str2, Qt::CaseSensitivity cs=Qt::CaseSensitive)
Fuzzy compare for short strings (like ICAO designators)
QString removeChars(const QString &s, F predicate)
Return a string with characters removed that match the given predicate.
Definition: stringutils.h:35
SWIFT_MISC_EXPORT QString removeDateTimeSeparators(const QString &s)
Remove the typical separators such as "-", " ".
SWIFT_MISC_EXPORT QMap< QString, QString > parseIniValues(const QString &data)
Obtain ini file like values, e.g. foo=bar.
SWIFT_MISC_EXPORT QString simplifyByDecomposition(const QString &candidate)
Remove accents / diacritic marks from a string by doing a Unicode decomposition and removing mark cha...
SWIFT_MISC_EXPORT int nthIndexOf(const QString &string, QChar ch, int nth=1, Qt::CaseSensitivity cs=Qt::CaseInsensitive)
nth index of ch
SWIFT_MISC_EXPORT bool caseInsensitiveStringCompare(const QString &c1, const QString &c2)
Case insensitive string compare.
SWIFT_MISC_EXPORT const QString & boolToOnOff(bool v)
Bool to on/off.
SWIFT_MISC_EXPORT QString removeSurroundingQuotes(const QString &in)
Remove surrounding quotes "foo" -> foo.
SWIFT_MISC_EXPORT double parseFraction(const QString &fraction, double failDefault=std::numeric_limits< double >::quiet_NaN())
Parse a fraction like 2/3.
SWIFT_MISC_EXPORT bool hasBalancedQuotes(const QString &in, char quote='"')
Has balanced quotes.
SWIFT_MISC_EXPORT QString dotToLocaleDecimalPoint(QString &input)
Replace dot '.' by locale decimal point.
SWIFT_MISC_EXPORT QString simplifyAccents(const QString &candidate)
Remove accents / diacritic marks from a string.
SWIFT_MISC_EXPORT bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs)
String compare.
SWIFT_MISC_EXPORT QString inQuotes(const QString &in, bool ignoreEmpty=false)
Return string in quotes.
SWIFT_MISC_EXPORT QString removeSurroundingApostrophes(const QString &in)
Remove surrounding apostrophes 'foo' -> foo.
SWIFT_MISC_EXPORT QString joinStringSet(const QSet< QString > &set, const QString &separator)
Convert string to bool.
SWIFT_MISC_EXPORT const QString & boolToNullNotNull(bool isNull)
Bool isNull to null/no null.
SWIFT_MISC_EXPORT QStringList splitLines(const QString &s)
Split a string into multiple lines. Blank lines are skipped.
SWIFT_MISC_EXPORT QStringList textCodecNames(bool simpleNames, bool mibNames)
Strip a designator from a combined string.
SWIFT_MISC_EXPORT QString removeComments(const QString &in, bool removeSlash, bool removeDoubleSlash)
Remove comments such as /‍** **‍/ or //.
SWIFT_MISC_EXPORT const QString & boolToEnabledDisabled(bool v)
Bool to enabled/disabled.
QList< QStringRef > splitStringRefs(const QString &s, F predicate)
Split a string into multiple strings, using a predicate function to identify the split points.
Definition: stringutils.h:92
QStringList splitString(const QString &s, F predicate)
Split a string into multiple strings, using a predicate function to identify the split points.
Definition: stringutils.h:120
SWIFT_MISC_EXPORT bool stringToBool(const QString &boolString)
Convert string to bool.
SWIFT_MISC_EXPORT bool containsAny(const QString &testString, const QStringList &any, Qt::CaseSensitivity cs)
Contains any string of the list?
SWIFT_MISC_EXPORT const QString & boolToTrueFalse(bool v)
Bool to true/false.
bool isDigitsOnlyString(const QString &testString)
String with digits only.
Definition: stringutils.h:168
SWIFT_MISC_EXPORT QDateTime fromStringUtc(const QString &dateTimeString, const QString &format)
Same as QDateTime::fromString but QDateTime will be set to UTC.
SWIFT_MISC_EXPORT const QString & defaultIfEmpty(const QString &candidate, const QString &defaultIfEmpty)
Default string if string is empty.
SWIFT_MISC_EXPORT const QString & boolToYesNo(bool v)
Bool to yes/no.
SWIFT_MISC_EXPORT QDateTime parseDateTimeStringOptimized(const QString &dateTimeString)
Parse yyyyMMddHHmmsszzz strings optimized.
SWIFT_MISC_EXPORT QList< QStringRef > splitLinesRefs(const QString &s)
Split a string into multiple lines. Blank lines are skipped.
std::string toLower(std::string s)
String to lower case.
Definition: qtfreeutils.h:113