-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstring-tools.js
376 lines (369 loc) · 11.1 KB
/
string-tools.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
//replace all occurances of string
export function replaceAll(currentString, stringToReplace, replacement) {
return currentString.replace(new RegExp(stringToReplace, ["g"]), replacement);
}
//this is ghetto hacked for now, handles only single characters and only a subset
export function stringRemove(text, thingsToRemove) {
var regExSymbols = [".", "$", "^"];
thingsToRemove = [].concat(thingsToRemove);
for (var i = 0; i < thingsToRemove.length; i++) {
var regex = thingsToRemove[i];
if (regExSymbols.indexOf(regex) != -1) {
regex = "\\" + regex;
}
text = text.replace(new RegExp(regex, ["g"]), "");
}
return text;
}
//pads string to length with character
export function pad(text, length, padChar) {
text = text.toString();
padChar = padChar || "0";
var lengthToPad = length - text.length;
if (lengthToPad > 0) {
for (var i = 0; i < lengthToPad; i++) {
text = padChar + text;
}
}
return text;
}
//pads string end to length with character
export function padEnd(text, length, pad) {
text = text.toString();
pad = pad || "0";
var lengthToPad = length - text.length;
if (lengthToPad > 0) {
for (var i = 0; i < lengthToPad; i++) {
text = text + pad;
}
}
return text;
}
//truncates with ellipsis
export function truncate(text, length) {
if (text.length > length) {
var truncatedText = text.substring(0, length - 4);
return truncatedText + "...";
}
return text;
}
//takes number and converts to bytes
export function getUnitSuffixedBytes(bytes, significantDecimal) {
var unitSuffix = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
var currentSuffixIndex = 0;
while (bytes >= 1024) {
bytes = bytes / 1024;
currentSuffixIndex++;
}
var rounded = significantDecimal === undefined ? bytes : bytes.toFixed(significantDecimal);
return rounded + " " + unitSuffix[currentSuffixIndex];
}
//adds s to word if count > 1 or 0
export function pluralize(word, count) {
return count === 0 || count > 1 ? word + 's' : word;
}
//capitalizes first letter
export function capitalizeFirst(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
export function lowerCaseFirst(str) {
return str.charAt(0).toLowerCase() + str.slice(1);
}
//capitalizes all words
export function capitalizeAll(str) {
return str.replace(/(?:^|\s)\S/g, function(a) {
return a.toUpperCase();
});
}
export function kebabCase(str) {
return str.replace(/\s+/g, "-").toLowerCase();
}
//generates a random string
export function generateRandomString(length) {
var s = Math.random().toString(36).substring(2);
while (s.length < length) { //possible to get a round number like 0.5 or run out of digits so append
s += Math.random().toString(36).substring(2);
}
return s.substring(0, length);
}
//trims length from end of string
export function stringTrimEnd(str, length) {
return str.substring(0, str.length - length);
}
//checks if string ends with string
export function stringEndsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
export function getCodes(str) {
var codeStr = "";
for (var i = 0; i < str.length; i++) {
codeStr += str.charCodeAt(i) + ",";
}
return codeStr;
}
export function getEscapes(str) {
var codeStr = "";
for (var i = 0; i < str.length; i++) {
codeStr += getEscape(str[i]);
}
return codeStr;
}
export function getEscape(char) {
if (char.charCodeAt(0) == 10) {
return "\\n";
}
if (char.charCodeAt(0) == 9) {
return "\\t";
}
if (char.charCodeAt(0) == 13) {
return "\\r";
}
if (char.charCodeAt(0) == 32) {
return "\\s";
}
return char;
}
export function isAlphanumeric(character) {
return /^[a-z0-9]+$/i.test(character);
}
export function isNumber(str) {
if (str === null || str === "") {
return false;
}
return !isNaN(str);
}
export function isAlpha(character) {
return /^[a-zA-Z]+$/.test(character);
}
export function isWhitespace(char) {
var whitespace = [
String.fromCharCode(13), //carriage return
String.fromCharCode(10), //new line
String.fromCharCode(32), //space
String.fromCharCode(9) //tab
];
return whitespace.indexOf(char) != -1;
}
export function spliceString(str, index, count, add) {
return str.slice(0, index) + add + str.slice(index + count);
}
export function insertString(text, index, textToInsert) {
return text.slice(0, index) + textToInsert + text.slice(index);
}
export function printStringAsTable(str) {
var table = [];
for (var i = 0; i < str.length; i++) {
table[i] = {
char: str[i]
};
}
console.table(table);
}
export function printStringAsTableHorizontal(str) {
var table = [{}];
for (var i = 0; i < str.length; i++) {
table[0][i] = str[i];
}
console.table(table);
}
export function stringToFileUrl(text) {
var file = new Blob([text], {
type: 'text/plain'
});
return Url.createObjectURL(file);
}
export function lengthChunk(text, chunkLength) {
var chunks = [];
var remaining = text;
while (remaining.length > chunkLength) {
chunks.push(remaining.substring(0, chunkLength));
remaining = remaining.substr(chunkLength);
}
chunks.push(remaining);
return chunks;
}
export function countChunk(text, count) {
var chunks = [];
var chunkLength = Math.ceil(text.length / count);
for (var i = 0; i < count; i++) {
chunks.push(text.substring(i * chunkLength, (i + 1) * chunkLength));
}
return chunks;
}
export function lengthChunkWords(text, chunkLength) {
var chunks = [];
var words = text.split(" ");
var currentChunk = "";
var i = 0;
while (i < words.length) {
currentChunk = "";
while (i < words.length && (currentChunk.length - 1) + words[i].length <= chunkLength) {
currentChunk += words[i] + " ";
i++;
}
if (i < words.length && words[i].length > chunkLength) {
throw "a word was bigger than chunk length: " + chunkLength;
}
currentChunk = stringTrimEnd(currentChunk, 1);
chunks.push(currentChunk);
}
return chunks;
}
export function truncateWords(text, length){
var words = text.split(" ");
var truncated = "";
var i = 0;
if(!length || text.length <= length){
return text;
}
while(truncated.length < length && i < words.length){
truncated += (i === 0 ? "" : " ") + words[i];
i++;
}
if(truncated.length <= length && i < words.length){
truncated += "...";
}
while(truncated.length > length){//overshot with ellipsis, walk back until it fits
truncated = truncated.substring(0, truncated.lastIndexOf(" ")) + "...";
}
return truncated;
}
export function htmlStringToDom(htmlString) {
parser = new DOMParser();
return parser.parseFromString(htmlString, "text/html");
}
export function transformToken(text, regex, replaceFunc) {
var matches = text.match(regex);
if (!matches) {
return text;
}
for (var i = 0; i < matches.length; i++) {
text = text.replace(matches[i], replaceFunc(matches[i]));
}
return text;
}
export function splitCamelCase(text) {
return text.replace(/([A-Z])/g, ' $1').split(" ");
}
export function camelCaseToDashed(text) {
return text.replace(/([A-Z])/g, '-$1').toLowerCase();
}
export function dashedToCamelCase(text) {
var parts = text.split("-");
for (var i = 0; i < parts.length; i++) {
if (i === 0) {
continue;
}
if (parts[i].length > 0) {
parts[i] = parts[i].charAt(0).toUpperCase() + parts[i].slice(1);
}
}
return parts.join("");
}
export function collapseWhitespace(text) {
return text.replace(/\s{2,}/g, ' ');
}
export function splitWhitespace(text) {
var split = [];
var buffer = "";
var quoted = false;
var readWhitespace = false;
for (var i = 0; i < text.length; i++) {
if (isWhitespace(text[i]) && !quoted && !readWhitespace) {
split.push(buffer);
buffer = "";
readWhitespace = true;
} else if (isWhitespace(text[i]) && !quoted && readWhitespace) {
continue;
} else if (text[i] == "\"" && !quoted) {
quoted = true;
readWhitespace = false;
} else if (text[i] == "\"" && quoted) {
quoted = false;
readWhitespace = false;
} else {
buffer += text[i];
readWhitespace = false;
}
}
if (buffer) {
split.push(buffer);
}
return split;
}
export function templateString(text, values) {
for (var key in values) {
var regex = new RegExp("\\${" + key + "}", "g");
text = text.replace(regex, values[key]);
}
return text;
}
export function parseLiteralList(list) {
return list.split(/(?!\B"[^"]*),(?![^"]*"\B)/g).map(function(item) {
var value = item.trim();
if (isNumber(value)) {
return parseFloat(value);
}
if (value === "false") {
return false;
}
if (value === "true") {
return true;
}
if (value === "null") {
return null;
}
if (value === "undefined") {
return undefined;
}
return value.replace(/\"/g, "");
});
}
export function mixedByteArrayToString(array) {
var result = "";
for (var i = 0; i < array.length; i++) {
var value = array[i];
if (typeof(value) === "string") {
result += value;
} else if (typeof(value) === "number") {
result += String.fromCharCode(value);
}
}
return result;
}
export const getStringInit = str =>
str.substring(0, str.length - 1);
export function getLevenshteinDistance(stringA, stringB, memo = new Map()){
if(!stringA){
return stringB.length;
}
if(!stringB){
return stringA.length;
}
const cost = stringA.charAt(stringA.length - 1) === stringB.charAt(stringB.length - 1)
? 0
: 1;
return Math.min(
getLevenshteinDistance(getStringInit(stringA), stringB) + 1,
getLevenshteinDistance(stringA, getStringInit(stringB)) + 1,
getLevenshteinDistance(getStringInit(stringA), getStringInit(stringB)) + cost
);
}
export function parseXsv(xsv, { valueDelimiter = "\t", lineDelimiter = "\n"} = {}){
return xsv.split(lineDelimiter)
.filter(x => x.trim() !== "")
.map(line => line.split(valueDelimiter)
.filter(v => v.trim())
.map(v => v.trim()));
}
export function parseKeyVals(txt, { valueDelimiter = ":", lineDelimiter = "\n"} = {}){
const keyvals = txt.split(lineDelimiter)
.filter(x => x.trim() !== "")
.map(kv => kv.split(valueDelimiter))
.filter(x => x.length > 1)
.map(x => x.map(y => y.trim()));
return Object.fromEntries(keyvals);
}
export function hashString(txt){
return SubtleCrypto.digest("sha-256", new TextEncoder().encode(txt));
}