KanoopCommonQt 2.1.1
Kanoop foundational Qt utility library
Loading...
Searching...
No Matches
stringutil.h
1/**
2 * StringUtil
3 *
4 * Some static helper methods for converting strings to and from other types.
5 *
6 * Additionally, methods exist for fuzzy string comparisons using the BITAP
7 * and Levenshtein Distance algorithms.
8 *
9 * Stephen Punak, February 12 2021
10 */
11#ifndef STRINGUTIL_H
12#define STRINGUTIL_H
13
14#include <QChar>
15#include <QList>
16#include <QString>
17#include <QStringList>
18#include <QUuid>
19#include "kanoopcommon.h"
20
21/**
22 * @brief Static helper methods for string conversion, manipulation, and fuzzy matching.
23 *
24 * Provides conversions between strings and common types (bool, double, QByteArray),
25 * trimming, splitting with quote awareness, and fuzzy matching via the BITAP and
26 * Levenshtein Distance algorithms.
27 */
28class KANOOP_EXPORT StringUtil
29{
30public:
31 /**
32 * @brief Convert the given string to a boolean.
33 *
34 * "true" (case-insensitive) or "1" yields true; everything else yields false.
35 * @param value String to convert
36 * @return Resulting boolean
37 */
38 static bool toBool(const QString& value) { return value.toLower() == "true" || value == "1"; }
39 /**
40 * @brief Convert an integer to a boolean.
41 * @param value Integer to convert (0 = false, non-zero = true)
42 * @return Resulting boolean
43 */
44 static bool toBool(int value) { return value != 0; }
45 /**
46 * @brief Convert a string to a byte array.
47 * @param value String to convert
48 * @return Resulting QByteArray
49 */
50 static QByteArray toByteArray(const QString& value);
51 /**
52 * @brief Convert a boolean to a string ("true" or "false").
53 * @param value Boolean to convert
54 * @return "true" or "false"
55 */
56 static QString toString(bool value) { return value ? "true" : "false"; }
57 /**
58 * @brief Convert a double to a string, trimming trailing zeros.
59 * @param value Double to convert
60 * @param precision Maximum number of decimal places
61 * @return Formatted string
62 */
63 static QString toString(double value, int precision = 6);
64 /**
65 * @brief Convert a byte array to a hex string.
66 * @param value Byte array to convert
67 * @param delimiter Separator between hex bytes
68 * @return Hex string representation
69 */
70 static QString toString(const QByteArray& value, const QString& delimiter = QString(" "));
71 /**
72 * @brief Convert a byte array to a hexadecimal table.
73 * @param buffer Byte array to display
74 * @param showOffset Whether to show byte offsets
75 * @param showText Whether to show ASCII text column
76 * @param tableWidth Number of bytes per row
77 * @return Formatted hex table string
78 */
79 static QString toHexTable(const QByteArray& buffer, bool showOffset = true, bool showText = true, int tableWidth = 16);
80 /**
81 * @brief Convert a list of QUuids to a string.
82 * @param value List of UUIDs
83 * @param delimiter Separator between UUIDs
84 * @return Delimited string of UUIDs
85 */
86 static QString toString(const QList<QUuid>& value, const QString& delimiter = QString(" "));
87 /**
88 * @brief Convert a delimited string to a list of UUIDs.
89 * @param value Delimited string containing UUIDs
90 * @param delimiter Separator between UUIDs
91 * @return List of parsed QUuids
92 */
93 static QList<QUuid> uuidsFromString(const QString& value, const QString& delimiter = QString(" "));
94 /**
95 * @brief Convert a list of strings to a single delimited string.
96 * @param list String list to join
97 * @param delimiter Separator character
98 * @return Joined string
99 */
100 static QString toDelimitedString(const QStringList& list, char delimiter = ' ');
101 /**
102 * @brief Convert a list of ints to a single delimited string.
103 * @param list Integer list to join
104 * @param delimiter Separator character
105 * @return Joined string
106 */
107 static QString toDelimitedString(const QList<int>& list, char delimiter = ' ');
108 /**
109 * @brief Convert a list of uint8_t values to a single delimited string.
110 * @param list Byte list to join
111 * @param delimiter Separator character
112 * @return Joined string
113 */
114 static QString toDelimitedString(const QList<uint8_t>& list, char delimiter = ' ');
115 /**
116 * @brief Format a byte count as an abbreviated string (K, M, G).
117 * @param byteCount Number of bytes
118 * @return Abbreviated string (e.g. "1.5 M")
119 */
120 static QString toKMG(qint64 byteCount);
121 /**
122 * @brief Trim the given characters from the front of the string.
123 * @param value Source string
124 * @param chars Characters to trim
125 * @return Trimmed string
126 */
127 static QString trimFront(const QString& value, const QList<QChar> &chars);
128
129 /**
130 * @brief Trim trailing whitespace from the string.
131 * @param value Source string
132 * @return String with trailing whitespace removed
133 */
134 static QString trimEnd(const QString& value);
135 /**
136 * @brief Trim the given characters from the end of the string.
137 * @param value Source string
138 * @param chars Characters to trim
139 * @return Trimmed string
140 */
141 static QString trimEnd(const QString& value, const QList<QChar> &chars);
142 /**
143 * @brief Trim the given characters from both ends of the string.
144 * @param value Source string
145 * @param chars Characters to trim
146 * @return Trimmed string
147 */
148 static QString trimBothEnds(const QString& value, const QList<QChar> &chars);
149
150 /**
151 * @brief Return the region between the outermost quotes.
152 * @param value Quoted string
153 * @return Unquoted content
154 */
155 static QString unquoted(const QString& value);
156 /**
157 * @brief Wrap a string in double quotes.
158 * @param value String to quote
159 * @return Quoted string
160 */
161 static QString quoted(const QString& value) { return QString("\"%1\"").arg(value); }
162
163 /**
164 * @brief Return a list of all the strings trimmed.
165 * @param value String list to trim
166 * @param behavior Whether to keep or skip empty parts
167 * @return List of trimmed strings
168 */
169 static QStringList trimmed(const QStringList& value, Qt::SplitBehavior behavior = Qt::KeepEmptyParts);
170
171 /**
172 * @brief Split the string respecting quoted substrings.
173 * @param value String to split
174 * @param separator Separator character
175 * @param behavior Whether to keep or skip empty parts
176 * @return Split string list
177 */
178 static QStringList splitWithQuotes(const QString& value, QChar separator, Qt::SplitBehavior behavior = Qt::KeepEmptyParts);
179 /**
180 * @brief Split the string respecting quoted substrings, using multiple separators.
181 * @param value String to split
182 * @param separators List of separator characters
183 * @param behavior Whether to keep or skip empty parts
184 * @return Split string list
185 */
186 static QStringList splitWithQuotes(const QString& value, QList<QChar> separators, Qt::SplitBehavior behavior = Qt::KeepEmptyParts);
187
188 /**
189 * @brief Combine strings from the list until hitting one that ends with an EOL character.
190 * @param lines Source string list
191 * @param index Starting index
192 * @param eolCharacter End-of-line character to look for
193 * @param consumed Output set to the number of lines consumed (may be nullptr)
194 * @return Combined string
195 */
196 static QString combineToEol(const QStringList& lines, int index, const QChar& eolCharacter = ';', int* consumed = nullptr);
197
198 /**
199 * @brief Return the character index of a given word number (1-based) in the string.
200 * @param value Source string
201 * @param wordNumber 1-based word ordinal
202 * @return Character index of the word, or -1 if not found
203 */
204 static int indexOfWord(const QString &value, int wordNumber);
205
206 /**
207 * @brief Calculate the index of a fuzzy match using the BITAP algorithm.
208 * @param needle Pattern to search for
209 * @param haystack String to search in
210 * @param maxDistance Maximum Levenshtein distance for a match
211 * @return Index of the match, or -1 if not found
212 */
213 static int fuzzyIndexOf(const QString& needle, const QString& haystack, int maxDistance = 1);
214
215 /**
216 * @brief Calculate the Levenshtein distance between two strings.
217 * @param s1 First string
218 * @param s2 Second string
219 * @return Edit distance between the strings
220 */
221 static int levenshteinDistance(const QString& s1, const QString& s2);
222
223 /**
224 * @brief Implements BITAP algorithm for fuzzy search.
225 */
226 class Bitap
227 {
228 public:
229 /**
230 * @brief Construct a Bitap fuzzy search and compute the result.
231 * @param haystack String to search in
232 * @param needle Pattern to search for
233 * @param maxDistance Maximum allowed Levenshtein distance
234 */
235 Bitap(const QString& haystack, const QString& needle, int maxDistance = 1);
236
237 /**
238 * @brief Return the index of the fuzzy match.
239 * @return Match index, or -1 if no match was found
240 */
241 int index() const { return _index; }
242
243 private:
244 int calculate(int maxDistance);
245
246 QString _haystack;
247 QString _needle;
248
249 int _index;
250 };
251
252 /**
253 * @brief Implements the Levenshtein algorithm to determine the distance
254 * between two strings.
255 */
257 {
258 public:
259 /**
260 * @brief Construct a Levenshtein calculator and compute the distance.
261 * @param s1 First string
262 * @param s2 Second string
263 */
264 Levenshtein(const QString& s1, const QString& s2);
265
266 /**
267 * @brief Return the computed Levenshtein distance.
268 * @return Edit distance
269 */
270 int distance() const { return _distance; }
271
272 private:
273 int min(int a, int b, int c)
274 {
275 int result = -1;
276 if(a <= b && a <= c) {
277 result = a;
278 }
279 else if(b <= a && b <= c) {
280 result = b;
281 }
282 else if(c <= a && c <= b) {
283 result = c;
284 }
285 return result;
286 }
287 int _distance;
288 };
289
290private:
291 class StringSplitter
292 {
293 public:
294 static QStringList splitWithQuotes(const QString& value, QChar separator, Qt::SplitBehavior behavior = Qt::KeepEmptyParts);
295 static QStringList splitWithQuotes(const QString& value, QList<QChar> separators, Qt::SplitBehavior behavior = Qt::KeepEmptyParts);
296
297 private:
298 StringSplitter(const QString& value, QList<QChar> separators, Qt::SplitBehavior behavior = Qt::KeepEmptyParts) :
299 _originalString(value), _separators(separators), _behavior(behavior), _inQuote(false) {}
300
301 void performSplit();
302 void appendCurrent();
303
304 QString _originalString;
305 QList<QChar> _separators;
306 Qt::SplitBehavior _behavior;
307
308 QString _current;
309 bool _inQuote;
310
311 QStringList _result;
312
313 static const char QUOTE = '\"';
314 };
315
316 class StringCombiner
317 {
318 public:
319 static QString combineToEol(const QStringList& lines, int index, const QChar& eolCharacter, int* consumed = nullptr);
320 };
321
322 static const char QUOTE = '\"';
323 static const char COLON = ':';
324};
325
326#endif // STRINGUTIL_H
Implements BITAP algorithm for fuzzy search.
Definition stringutil.h:227
int index() const
Return the index of the fuzzy match.
Definition stringutil.h:241
Bitap(const QString &haystack, const QString &needle, int maxDistance=1)
Construct a Bitap fuzzy search and compute the result.
Implements the Levenshtein algorithm to determine the distance between two strings.
Definition stringutil.h:257
int distance() const
Return the computed Levenshtein distance.
Definition stringutil.h:270
Levenshtein(const QString &s1, const QString &s2)
Construct a Levenshtein calculator and compute the distance.
StringUtil.
Definition stringutil.h:29
static QString trimEnd(const QString &value, const QList< QChar > &chars)
Trim the given characters from the end of the string.
static bool toBool(int value)
Convert an integer to a boolean.
Definition stringutil.h:44
static QString toDelimitedString(const QList< uint8_t > &list, char delimiter=' ')
Convert a list of uint8_t values to a single delimited string.
static QString combineToEol(const QStringList &lines, int index, const QChar &eolCharacter=';', int *consumed=nullptr)
Combine strings from the list until hitting one that ends with an EOL character.
static QString trimEnd(const QString &value)
Trim trailing whitespace from the string.
static QString quoted(const QString &value)
Wrap a string in double quotes.
Definition stringutil.h:161
static QString toDelimitedString(const QStringList &list, char delimiter=' ')
Convert a list of strings to a single delimited string.
static QString unquoted(const QString &value)
Return the region between the outermost quotes.
static QStringList trimmed(const QStringList &value, Qt::SplitBehavior behavior=Qt::KeepEmptyParts)
Return a list of all the strings trimmed.
static QString trimBothEnds(const QString &value, const QList< QChar > &chars)
Trim the given characters from both ends of the string.
static int levenshteinDistance(const QString &s1, const QString &s2)
Calculate the Levenshtein distance between two strings.
static QString toString(bool value)
Convert a boolean to a string ("true" or "false").
Definition stringutil.h:56
static QString toHexTable(const QByteArray &buffer, bool showOffset=true, bool showText=true, int tableWidth=16)
Convert a byte array to a hexadecimal table.
static QStringList splitWithQuotes(const QString &value, QChar separator, Qt::SplitBehavior behavior=Qt::KeepEmptyParts)
Split the string respecting quoted substrings.
static int indexOfWord(const QString &value, int wordNumber)
Return the character index of a given word number (1-based) in the string.
static int fuzzyIndexOf(const QString &needle, const QString &haystack, int maxDistance=1)
Calculate the index of a fuzzy match using the BITAP algorithm.
static QByteArray toByteArray(const QString &value)
Convert a string to a byte array.
static QString toKMG(qint64 byteCount)
Format a byte count as an abbreviated string (K, M, G).
static QString trimFront(const QString &value, const QList< QChar > &chars)
Trim the given characters from the front of the string.
static QStringList splitWithQuotes(const QString &value, QList< QChar > separators, Qt::SplitBehavior behavior=Qt::KeepEmptyParts)
Split the string respecting quoted substrings, using multiple separators.
static QString toDelimitedString(const QList< int > &list, char delimiter=' ')
Convert a list of ints to a single delimited string.
static QString toString(const QList< QUuid > &value, const QString &delimiter=QString(" "))
Convert a list of QUuids to a string.
static QString toString(double value, int precision=6)
Convert a double to a string, trimming trailing zeros.
static bool toBool(const QString &value)
Convert the given string to a boolean.
Definition stringutil.h:38
static QList< QUuid > uuidsFromString(const QString &value, const QString &delimiter=QString(" "))
Convert a delimited string to a list of UUIDs.
static QString toString(const QByteArray &value, const QString &delimiter=QString(" "))
Convert a byte array to a hex string.