swift
Loading...
Searching...
No Matches
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 <algorithm>
9#include <any>
10
11#include <QChar>
12#include <QRegularExpression>
13#include <QStringBuilder>
14#include <QTimeZone>
15
16namespace swift::misc
17{
18 QString removeDateTimeSeparators(const QString &s)
19 {
20 return removeChars(s, [](QChar c) { return c == u' ' || c == u':' || c == u'_' || c == u'-' || c == u'.'; });
21 }
22
23 QList<QStringView> splitLinesRefs(const QString &s)
24 {
25 return splitStringRefs(s, [](QChar c) { return c == '\n' || c == '\r'; });
26 }
27
28 QStringList splitLines(const QString &s)
29 {
30 return splitString(s, [](QChar c) { return c == '\n' || c == '\r'; });
31 }
32
33 QByteArray utfToPercentEncoding(const QString &s, const QByteArray &allow, char percent)
34 {
35 QByteArray result;
36 for (const QChar &c : s)
37 {
38 if (const char latin = c.toLatin1())
39 {
40 if ((latin >= 'a' && latin <= 'z') || (latin >= 'A' && latin <= 'Z') ||
41 (latin >= '0' && latin <= '9') || allow.contains(latin))
42 {
43 result += c.toLatin1();
44 }
45 else
46 {
47 result += percent;
48 if (latin < 0x10)
49 {
50 result += '0';
51 }
52 result += QByteArray::number(static_cast<int>(latin), 16);
53 }
54 }
55 else
56 {
57 result += percent;
58 result += 'x';
59 const ushort unicode = c.unicode();
60 if (unicode < 0x0010)
61 {
62 result += '0';
63 }
64 if (unicode < 0x0100)
65 {
66 result += '0';
67 }
68 if (unicode < 0x1000)
69 {
70 result += '0';
71 }
72 result += QByteArray::number(unicode, 16);
73 }
74 }
75 return result;
76 }
77
78 QString utfFromPercentEncoding(const QByteArray &ba, char percent)
79 {
80 QString result;
81 for (int i = 0; i < ba.size(); ++i)
82 {
83 if (ba[i] == percent)
84 {
85 ++i;
86 Q_ASSERT(i < ba.size());
87 if (ba[i] == 'x')
88 {
89 ++i;
90 Q_ASSERT(i < ba.size());
91 result += QChar(ba.mid(i, 4).toInt(nullptr, 16));
92 i += 3;
93 }
94 else
95 {
96 result += static_cast<char>(ba.mid(i, 2).toInt(nullptr, 16));
97 ++i;
98 }
99 }
100 else
101 {
102 result += ba[i];
103 }
104 }
105 return result;
106 }
107
108 const QString &boolToOnOff(bool v)
109 {
110 static const QString on("on");
111 static const QString off("off");
112 return v ? on : off;
113 }
114
115 const QString &boolToYesNo(bool v)
116 {
117 static const QString yes("yes");
118 static const QString no("no");
119 return v ? yes : no;
120 }
121
122 const QString &boolToTrueFalse(bool v)
123 {
124 static const QString t("true");
125 static const QString f("false");
126 return v ? t : f;
127 }
128
129 const QString &boolToEnabledDisabled(bool v)
130 {
131 static const QString e("enabled");
132 static const QString d("disabled");
133 return v ? e : d;
134 }
135
136 const QString &boolToNullNotNull(bool isNull)
137 {
138 static const QString n("null");
139 static const QString nn("not null");
140 return isNull ? n : nn;
141 }
142
143 bool stringToBool(const QString &string)
144 {
145 QString s(string.trimmed().toLower());
146 if (s.isEmpty())
147 {
148 return false;
149 }
150
151 // 1 char values
152 const QChar c = s.at(0);
153 if (c == '1' || c == 't' || c == 'y' || c == 'x')
154 {
155 return true;
156 }
157 if (c == '0' || c == 'f' || c == 'n' || c == '_')
158 {
159 return false;
160 }
161
162 if (c == 'e')
163 {
164 return true;
165 } // enabled
166 if (c == 'd')
167 {
168 return false;
169 } // disabled
170
171 // full words
172 if (s == "on")
173 {
174 return true;
175 }
176 return false;
177 }
178
179 int fuzzyShortStringComparision(const QString &str1, const QString &str2, Qt::CaseSensitivity cs)
180 {
181 // same
182 if (cs == Qt::CaseInsensitive)
183 {
184 if (caseInsensitiveStringCompare(str1, str2))
185 {
186 return 100;
187 }
188 }
189 else if (str1 == str2)
190 {
191 return 100;
192 }
193
194 // one string is empty
195 if (str1.isEmpty() || str2.isEmpty())
196 {
197 return 0;
198 }
199
200 // make sure aStr is not shorter
201 const QString aStr = str1.length() >= str2.length() ? str1 : str2;
202 const QString bStr = str1.length() >= str2.length() ? str2 : str1;
203
204 // starts/ends with
205 const auto s1 = static_cast<double>(aStr.length());
206 const auto s2 = static_cast<double>(bStr.length());
207 if (aStr.endsWith(bStr, cs))
208 {
209 return qRound(s1 / s2 * 100);
210 }
211 if (aStr.startsWith(bStr, cs))
212 {
213 return qRound(s1 / s2 * 100);
214 }
215
216 // contains
217 if (aStr.contains(bStr, cs))
218 {
219 return qRound(s1 / s2 * 100);
220 }
221
222 // char by char
223 double points = 0;
224 for (int p = 0; p < aStr.length(); p++)
225 {
226 if (p < bStr.length() && aStr[p] == bStr[p])
227 {
228 points += 1.0;
229 continue;
230 }
231
232 // char after
233 const int after = p + 1;
234 if (after < bStr.length() && aStr[p] == bStr[after])
235 {
236 points += 0.5;
237 continue;
238 }
239
240 // char before
241 const int before = p - 1;
242 if (before >= 0 && before < bStr.length() && aStr[p] == bStr[before])
243 {
244 points += 0.5;
245 continue;
246 }
247 }
248 return qRound(points / s1 * 100);
249 }
250
251 QString intToHex(int value, int digits)
252 {
253 const QString hex(QString::number(value, 16).toUpper());
254 const qsizetype l = hex.length();
255 if (l >= digits)
256 {
257 return hex.right(digits);
258 }
259 const qsizetype d = digits - l;
260 return QString(d, '0') + hex;
261 }
262
263 QString stripDesignatorFromCompleterString(const QString &candidate)
264 {
265 const QString s(candidate.trimmed().toUpper());
266 if (s.isEmpty())
267 {
268 return {};
269 }
270 return s.contains(' ') ? s.left(s.indexOf(' ')) : s;
271 }
272
273 // http://www.codegur.online/14009522/how-to-remove-accents-diacritic-marks-from-a-string-in-qt
274 // https://stackoverflow.com/questions/14009522/how-to-remove-accents-diacritic-marks-from-a-string-in-qt
275 // https://german.stackexchange.com/questions/4992/conversion-table-for-diacritics-e-g-%C3%BC-%E2%86%92-ue
276 QString simplifyAccents(const QString &candidate)
277 {
278 static const QString diacriticLetters =
279 QString::fromUtf8("ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ");
280 static const QStringList noDiacriticLetters(
281 { "S", "OE", "Z", "s", "oe", "z", "Y", "Y", "u", "A", "A", "A", "A", "A", "A", "AE", "C", "E",
282 "E", "E", "E", "I", "I", "I", "I", "D", "N", "O", "O", "O", "O", "O", "O", "U", "U", "U",
283 "U", "Y", "s", "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i",
284 "i", "o", "n", "o", "o", "o", "o", "o", "o", "u", "u", "u", "u", "y", "y" });
285
286 QString output = "";
287 for (const QChar c : candidate)
288 {
289 const qsizetype dIndex = diacriticLetters.indexOf(c);
290 if (dIndex < 0)
291 {
292 output.append(c);
293 }
294 else
295 {
296 const QString replacement = noDiacriticLetters[dIndex];
297 output.append(replacement);
298 }
299 }
300 return output;
301 }
302
303 QString simplifyByDecomposition(const QString &s)
304 {
305 QString result;
306 // QChar c (NOT QChar &c), see
307 // https://discordapp.com/channels/539048679160676382/539925070550794240/686321311076581440
308 for (const QChar &c : s)
309 {
311 {
312 result.push_back(c);
313 }
314 else
315 {
316 for (const QChar &dc : c.decomposition())
317 {
318 if (!dc.isMark())
319 {
320 result.push_back(dc);
321 }
322 }
323 }
324 }
325 return result;
326 }
327
328 bool caseInsensitiveStringCompare(const QString &c1, const QString &c2)
329 {
330 return c1.length() == c2.length() && c1.startsWith(c2, Qt::CaseInsensitive);
331 }
332
333 QString simplifyNameForSearch(const QString &name)
334 {
335 return removeChars(name.toUpper(), [](QChar c) { return !c.isUpper(); });
336 }
337
338 QDateTime fromStringUtc(const QString &dateTimeString, const QString &format)
339 {
340 if (dateTimeString.isEmpty() || format.isEmpty())
341 {
342 return {};
343 }
344 QDateTime dt = QDateTime::fromString(dateTimeString, format);
345 if (!dt.isValid())
346 {
347 return dt;
348 }
349 dt.setTimeZone(QTimeZone::utc()); // must only be applied to valid timestamps
350 return dt;
351 }
352
353 QDateTime fromStringUtc(const QString &dateTimeString, Qt::DateFormat format)
354 {
355 if (dateTimeString.isEmpty())
356 {
357 return {};
358 }
359 QDateTime dt = QDateTime::fromString(dateTimeString, format);
360 if (!dt.isValid())
361 {
362 return dt;
363 }
364 dt.setTimeZone(QTimeZone::utc()); // must only be applied to valid timestamps
365 return dt;
366 }
367
368 QDateTime fromStringUtc(const QString &dateTimeString, const QLocale &locale, QLocale::FormatType format)
369 {
370 if (dateTimeString.isEmpty())
371 {
372 return {};
373 }
374 QDateTime dt = locale.toDateTime(dateTimeString, format);
375 if (!dt.isValid())
376 {
377 return dt;
378 }
379 dt.setTimeZone(QTimeZone::utc()); // must only be applied to valid timestamps
380 return dt;
381 }
382
383 QDateTime parseMultipleDateTimeFormats(const QString &dateTimeString)
384 {
385 if (dateTimeString.isEmpty())
386 {
387 return {};
388 }
389 if (isDigitsOnlyString(dateTimeString))
390 {
391 // 2017 0301 124421 321
392 if (dateTimeString.length() == 17)
393 {
394 return fromStringUtc(dateTimeString, "yyyyMMddHHmmsszzz");
395 }
396 if (dateTimeString.length() == 14)
397 {
398 return fromStringUtc(dateTimeString, "yyyyMMddHHmmss");
399 }
400 if (dateTimeString.length() == 12)
401 {
402 return fromStringUtc(dateTimeString, "yyyyMMddHHmm");
403 }
404 if (dateTimeString.length() == 8)
405 {
406 return fromStringUtc(dateTimeString, "yyyyMMdd");
407 }
408 return {};
409 }
410
411 // remove simple separators and check if digits only again
412 const QString simpleSeparatorsRemoved = removeDateTimeSeparators(dateTimeString);
413 if (isDigitsOnlyString(simpleSeparatorsRemoved))
414 {
415 return parseMultipleDateTimeFormats(simpleSeparatorsRemoved);
416 }
417
418 // stupid trial and error
419 QDateTime ts = fromStringUtc(dateTimeString, Qt::ISODateWithMs);
420 if (ts.isValid()) return ts;
421
422 ts = fromStringUtc(dateTimeString, Qt::ISODate);
423 if (ts.isValid()) return ts;
424
425 ts = fromStringUtc(dateTimeString, Qt::TextDate);
426 if (ts.isValid()) return ts;
427
428 ts = fromStringUtc(dateTimeString, QLocale(), QLocale::LongFormat);
429 if (ts.isValid()) return ts;
430
431 ts = fromStringUtc(dateTimeString, QLocale(), QLocale::ShortFormat);
432 if (ts.isValid()) return ts;
433
434 // SystemLocaleShortDate,
435 // SystemLocaleLongDate,
436 return {};
437 }
438
439 QDateTime parseDateTimeStringOptimized(const QString &dateTimeString)
440 {
441 if (dateTimeString.length() < 8)
442 {
443 return {};
444 }
445
446 // yyyyMMddHHmmsszzz
447 // 01234567890123456
448 int year(QStringView { dateTimeString }.left(4).toInt());
449 int month(QStringView { dateTimeString }.mid(4, 2).toInt());
450 int day(QStringView { dateTimeString }.mid(6, 2).toInt());
451 QDate date;
452 date.setDate(year, month, day);
453 QDateTime dt;
455 dt.setDate(date);
456 if (dateTimeString.length() < 12)
457 {
458 return dt;
459 }
460
461 QTime t;
462 const int hour(QStringView { dateTimeString }.mid(8, 2).toInt());
463 const int minute(QStringView { dateTimeString }.mid(10, 2).toInt());
464 const int second(dateTimeString.length() < 14 ? 0 : QStringView { dateTimeString }.mid(12, 2).toInt());
465 const int ms(dateTimeString.length() < 17 ? 0 : QStringView { dateTimeString }.right(3).toInt());
466
467 t.setHMS(hour, minute, second, ms);
468 dt.setTime(t);
469 return dt;
470 }
471
472 QString dotToLocaleDecimalPoint(QString &input) { return input.replace('.', QLocale::system().decimalPoint()); }
473
474 QString dotToLocaleDecimalPoint(const QString &input)
475 {
476 QString copy(input);
477 return copy.replace('.', QLocale::system().decimalPoint());
478 }
479
480 bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs)
481 {
482 if (cs == Qt::CaseSensitive)
483 {
484 return c1 == c2;
485 }
486 return caseInsensitiveStringCompare(c1, c2);
487 }
488
489 QString inApostrophes(const QString &in, bool ignoreEmpty)
490 {
491 if (in.isEmpty())
492 {
493 return ignoreEmpty ? QString() : QStringLiteral("''");
494 }
495 return u'\'' % in % u'\'';
496 }
497
498 QString inQuotes(const QString &in, bool ignoreEmpty)
499 {
500 if (in.isEmpty())
501 {
502 return ignoreEmpty ? QString() : QStringLiteral("\"\"");
503 }
504 return u'"' % in % u'"';
505 }
506
507 QString withQuestionMark(const QString &question)
508 {
509 if (question.endsWith("?"))
510 {
511 return question;
512 }
513 return question % u'?';
514 }
515
516 qsizetype nthIndexOf(const QString &string, QChar ch, int nth, Qt::CaseSensitivity cs)
517 {
518 if (nth < 1 || string.isEmpty() || nth > string.length())
519 {
520 return -1;
521 }
522
523 qsizetype from = 0;
524 qsizetype ci = -1;
525 for (int t = 0; t < nth; ++t)
526 {
527 ci = string.indexOf(ch, from, cs);
528 if (ci < 0)
529 {
530 return -1;
531 }
532 from = ci + 1;
533 if (from >= string.length())
534 {
535 return -1;
536 }
537 }
538 return ci;
539 }
540
541 QString joinStringSet(const QSet<QString> &set, const QString &separator)
542 {
543 if (set.isEmpty())
544 {
545 return {};
546 }
547 if (set.size() == 1)
548 {
549 return *set.begin();
550 }
551 return set.values().join(separator);
552 }
553
554 QMap<QString, QString> parseIniValues(const QString &data)
555 {
556 QMap<QString, QString> map;
557 QList<QStringView> lines = splitLinesRefs(data);
558 for (const QStringView l : lines)
559 {
560 if (l.isEmpty())
561 {
562 continue;
563 }
564 const qsizetype i = l.indexOf('=');
565 if (i < 0 || i >= l.length() + 1)
566 {
567 continue;
568 }
569
570 const QString key = l.left(i).trimmed().toString();
571 const QString value = l.mid(i + 1).toString();
572 if (value.isEmpty())
573 {
574 continue;
575 }
576 map.insert(key, value);
577 }
578 return map;
579 }
580
581 QString removeSurroundingApostrophes(const QString &in)
582 {
583 if (in.size() < 2)
584 {
585 return in;
586 }
587 if (in.startsWith("'") && in.endsWith("'"))
588 {
589 return in.mid(1, in.length() - 2);
590 }
591 return in;
592 }
593
594 QString removeSurroundingQuotes(const QString &in)
595 {
596 if (in.size() < 2)
597 {
598 return in;
599 }
600 if (in.startsWith("\"") && in.endsWith("\""))
601 {
602 return in.mid(1, in.length() - 2);
603 }
604 return in;
605 }
606
607 QString removeComments(const QString &in, bool removeSlashStar, bool removeDoubleSlash)
608 {
609 QString copy(in);
610
611 thread_local const QRegularExpression re1(R"(\/\*(.|\n)*?\*\/)");
612 if (removeSlashStar)
613 {
614 copy.remove(re1);
615 }
616
617 thread_local const QRegularExpression re2("\\/\\/.*");
618 if (removeDoubleSlash)
619 {
620 copy.remove(re2);
621 }
622
623 return copy;
624 }
625
626 bool containsAny(const QString &testString, const QStringList &any, Qt::CaseSensitivity cs)
627 {
628 if (testString.isEmpty() || any.isEmpty())
629 {
630 return false;
631 }
632 return std::ranges::any_of(any, [&](const QString &a) { return testString.contains(a, cs); });
633 }
634
635 bool hasBalancedQuotes(const QString &in, char quote)
636 {
637 if (in.isEmpty())
638 {
639 return true;
640 }
641 const qsizetype c = in.count(quote);
642 return (c % 2) == 0;
643 }
644
645 double parseFraction(const QString &fraction, double failDefault)
646 {
647 if (fraction.isEmpty())
648 {
649 return failDefault;
650 }
651 bool ok {};
652
653 double r = failDefault;
654 if (fraction.contains('/'))
655 {
656 const QStringList parts = fraction.split('/');
657 if (parts.size() != 2)
658 {
659 return failDefault;
660 }
661 const double c = parts.front().trimmed().toDouble(&ok);
662 if (!ok)
663 {
664 return failDefault;
665 }
666
667 const double d = parts.last().trimmed().toDouble(&ok);
668 if (!ok)
669 {
670 return failDefault;
671 }
672 if (qFuzzyCompare(0.0, d))
673 {
674 return failDefault;
675 }
676 r = c / d;
677 }
678 else
679 {
680 r = fraction.trimmed().toDouble(&ok);
681 if (!ok)
682 {
683 return failDefault;
684 }
685 }
686 return r;
687 }
688
689 QString cleanNumber(const QString &number)
690 {
691 QString n = number.trimmed();
692 if (n.isEmpty())
693 {
694 return {};
695 }
696
697 qsizetype dp = n.indexOf('.');
698 if (dp < 0)
699 {
700 dp = n.indexOf(',');
701 }
702
703 // clean all trailing stuff
704 while (dp >= 0 && !n.isEmpty())
705 {
706 const QChar l = n.at(n.size() - 1);
707 if (l == '0')
708 {
709 n.chop(1);
710 continue;
711 }
712 if (l == '.' || l == ',')
713 {
714 n.chop(1);
715 }
716 break;
717 }
718
719 while (n.startsWith("00"))
720 {
721 n.remove(0, 1);
722 }
723
724 return n;
725 }
726
727} // namespace swift::misc
728
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 qsizetype nthIndexOf(const QString &string, QChar ch, int nth=1, Qt::CaseSensitivity cs=Qt::CaseInsensitive)
nth index of ch
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 const QString & boolToTrueFalse(bool v)
Bool to true/false.
SWIFT_MISC_EXPORT QString utfFromPercentEncoding(const QByteArray &ba, char percent='%')
Reverse utfFromPercentEncoding.
SWIFT_MISC_EXPORT const QString & boolToEnabledDisabled(bool v)
Bool to enabled/disabled.
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:34
SWIFT_MISC_EXPORT const QString & boolToOnOff(bool v)
Bool to on/off.
SWIFT_MISC_EXPORT QString removeDateTimeSeparators(const QString &s)
Remove the typical separators such as "-", " ".
SWIFT_MISC_EXPORT const QString & boolToYesNo(bool v)
Bool to yes/no.
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 bool caseInsensitiveStringCompare(const QString &c1, const QString &c2)
Case insensitive string compare.
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 const QString & boolToNullNotNull(bool isNull)
Bool isNull to null/no null.
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 QMap< QString, QString > parseIniValues(const QString &data)
Obtain ini file like values, e.g. foo=bar.
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.
QList< QStringView > splitStringRefs(const QString &s, F predicate)
Split a string into multiple strings, using a predicate function to identify the split points.
Definition stringutils.h:94
SWIFT_MISC_EXPORT QString joinStringSet(const QSet< QString > &set, const QString &separator)
Convert string to bool.
SWIFT_MISC_EXPORT QStringList splitLines(const QString &s)
Split a string into multiple lines. Blank lines are skipped.
SWIFT_MISC_EXPORT QString removeComments(const QString &in, bool removeSlash, bool removeDoubleSlash)
Remove comments such as /‍** **‍/ or //.
SWIFT_MISC_EXPORT QList< QStringView > splitLinesRefs(const QString &s)
Split a string into multiple lines. Blank lines are skipped.
QStringList splitString(const QString &s, F predicate)
Split a string into multiple strings, using a predicate function to identify the split points.
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?
bool isDigitsOnlyString(const QString &testString)
String with digits only.
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 QDateTime parseDateTimeStringOptimized(const QString &dateTimeString)
Parse yyyyMMddHHmmsszzz strings optimized.
bool contains(QByteArrayView bv) const const
QByteArray mid(qsizetype pos, qsizetype len) &&
QByteArray number(double n, char format, int precision)
qsizetype size() const const
int toInt(bool *ok, int base) const const
NoDecomposition
QString decomposition(char32_t ucs4)
QChar::Decomposition decompositionTag(char32_t ucs4)
bool setDate(int year, int month, int day)
QDateTime fromString(QStringView string, QStringView format, QCalendar cal)
bool isValid() const const
void setDate(QDate date, QDateTime::TransitionResolution resolve)
void setTime(QTime time, QDateTime::TransitionResolution resolve)
void setTimeZone(const QTimeZone &toZone, QDateTime::TransitionResolution resolve)
QList< T >::reference front()
bool isEmpty() const const
T & last()
qsizetype size() const const
QLocale system()
QDateTime toDateTime(const QString &string, QLocale::FormatType format, QCalendar cal, int baseYear) const const
QSet< T >::iterator begin()
bool isEmpty() const const
qsizetype size() const const
QList< T > values() const const
qsizetype count() const const
const QChar at(qsizetype position) const const
void chop(qsizetype n)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
QString fromUtf8(QByteArrayView str)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) &&
QString number(double n, char format, int precision)
void push_back(QChar ch)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
qsizetype size() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
double toDouble(bool *ok) const const
QString toUpper() const const
QString trimmed() const const
CaseSensitivity
DateFormat
QTextStream & hex(QTextStream &stream)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
std::string toLower(std::string s)
String to lower case.
bool setHMS(int h, int m, int s, int ms)
QTimeZone utc()