name:
src/Utilities/CriteriaFunctionFactory.ts
-rw-r--r--
3435
1/**
2 * Converts wild-card style expressions (in which * matches zero or more characters, and ? matches exactly one character)
3 * to regular expressions. * and ? can be escaped by prefixing with ~.
4 * For future reference, something like this might be better
5 * http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex.
6 * @param c input
7 * @returns {RegExp} resulting regex
8 */
9function wildCardRegex(c: string) {
10 let a = c.split("~?");
11 for (let i = 0; i < a.length; i++) {
12 a[i] = a[i].split("?").join(".{1}");
13 }
14 let b = a.join("\\\?");
15 let d = b.split("~*");
16 for (let i = 0; i < d.length; i++) {
17 d[i] = d[i].split("*").join(".*");
18 }
19 return new RegExp("^"+d.join(".*")+"$", "g");
20}
21
22
23
24
25/**
26 * Creates a criteria function to evaluate elements in a range in an *IF function.
27 */
28class CriteriaFunctionFactory {
29 /**
30 * If the criteria is a number, use strict equality checking.
31 * If the criteria is a string, check to see if it is a comparator.
32 * If the criteria is a string, and it is not a comparator, check for regex.
33 * If the criteria is a string and has not matched the above, finally use strict equality checking as a fallback.
34 * If the criteria has not been set, default to false-returning criteria function.
35 * @param criteria
36 * @returns {(x:any)=>boolean}
37 */
38 static createCriteriaFunction(criteria: string) : Function {
39 // Default criteria does nothing
40 let criteriaEvaluation = function (x) : boolean {
41 return false;
42 };
43
44 if (typeof criteria === "number" || typeof criteria === "boolean") {
45 criteriaEvaluation = function (x) : boolean {
46 return x === criteria;
47 };
48 } else if (typeof criteria === "string") {
49 let comparisonMatches = criteria.match(/^\s*(<=|>=|=|<>|>|<)\s*(-)?\s*(\$)?\s*([0-9]+([,.][0-9]+)?)\s*$/);
50 if (comparisonMatches !== null && comparisonMatches.length >= 6 && comparisonMatches[4] !== undefined) {
51 criteriaEvaluation = function (x) : boolean {
52 return eval(x + comparisonMatches[1] + (comparisonMatches[2] === undefined ? "" : "-") + comparisonMatches[4]);
53 };
54 if (comparisonMatches[1] === "=") {
55 criteriaEvaluation = function (x) : boolean {
56 return eval(x + "===" + (comparisonMatches[2] === undefined ? "" : "-") + comparisonMatches[4]);
57 };
58 }
59 if (comparisonMatches[1] === "<>") {
60 criteriaEvaluation = function (x) : boolean {
61 return eval(x + "!==" + (comparisonMatches[2] === undefined ? "" : "-") + comparisonMatches[4]);
62 };
63 }
64 } else if (criteria.match(/\*|\~\*|\?|\~\?/) !== null) {
65 // Regular string
66 let matches = criteria.match(/\*|\~\*|\?|\~\?/);
67 if (matches !== null) {
68 criteriaEvaluation = function (x) : boolean {
69 try {
70 // http://stackoverflow.com/questions/26246601/wildcard-string-comparison-in-javascript
71 return wildCardRegex(criteria).test(x);
72 } catch (e) {
73 return false;
74 }
75 };
76 } else {
77 criteriaEvaluation = function (x) : boolean {
78 return x === criteria;
79 };
80 }
81 } else {
82 criteriaEvaluation = function (x) : boolean {
83 return x === criteria;
84 };
85 }
86 }
87 return criteriaEvaluation;
88 }
89}
90
91export {
92 CriteriaFunctionFactory
93}