commit
message
Using DateRegExBuilder instead of hand-crafted regular expressions
author
Ben Vogt <[email protected]>
date
2017-03-26 22:50:23
stats
2 file(s) changed,
101 insertions(+),
0 deletions(-)
files
src/RawFormulas/Date.ts
src/RawFormulas/Utils.ts
1diff --git a/src/RawFormulas/Date.ts b/src/RawFormulas/Date.ts
2index 834e583..8f4fa71 100644
3--- a/src/RawFormulas/Date.ts
4+++ b/src/RawFormulas/Date.ts
5@@ -3,6 +3,7 @@ import * as moment from "moment";
6 import * as Formula from "formulajs"
7 import {
8 ArgsChecker,
9+ DateRegExBuilder,
10 TypeCaster
11 } from "./Utils";
12 import {
13@@ -138,7 +139,17 @@ var DATEVALUE = function (...values) : number {
14 // Check YYYY/MM/DD
15 if (m === undefined) {
16 // For reference: https://regex101.com/r/uusfi7/5
17- var matches = dateString.match(/^\s*(([0-9][0-9][0-9][0-9])|([1-9][0-9][0-9]))\/([1-9]|0[1-9]|1[0-2])\/([1-9]|[0-2][0-9]|3[0-1])\s*$/);
18+ var REG = /^\s*(([0-9][0-9][0-9][0-9])|([1-9][0-9][0-9]))\/([1-9]|0[1-9]|1[0-2])\/([1-9]|[0-2][0-9]|3[0-1])\s*$/;
19+ REG = DateRegExBuilder.DateRegExBuilder()
20+ .start()
21+ .YYYY()
22+ .SLASH_DELIMITOR()
23+ .MM()
24+ .SLASH_DELIMITOR()
25+ .DD()
26+ .end()
27+ .build();
28+ var matches = dateString.match(REG);
29 if (matches && matches.length === 6) {
30 var years = parseInt(matches[1]);
31 var months = parseInt(matches[4]) - 1; // Months are zero indexed.
32diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
33index 975f2c6..d0fdd86 100644
34--- a/src/RawFormulas/Utils.ts
35+++ b/src/RawFormulas/Utils.ts
36@@ -364,9 +364,97 @@ class Serializer {
37 }
38
39
40+/**
41+ * Build a regular expression step by step, to make it easier to build and read the resulting regular expressions.
42+ */
43+class DateRegExBuilder {
44+ private regexString = "";
45+ private static ZERO_OR_MORE_SPACES = "\\s*";
46+ private static ONE_OR_MORE_SPACES = "\\s+";
47+
48+ static DateRegExBuilder() : DateRegExBuilder {
49+ return new DateRegExBuilder();
50+ }
51+
52+ start() : DateRegExBuilder {
53+ this.regexString += "^" + DateRegExBuilder.ZERO_OR_MORE_SPACES;
54+ return this;
55+ }
56+
57+ end() : DateRegExBuilder {
58+ this.regexString += DateRegExBuilder.ZERO_OR_MORE_SPACES + "$";
59+ return this;
60+ }
61+
62+ /**
63+ * Adds a match group for zero or more whitespace tokens.
64+ * @returns {DateRegExBuilder}
65+ */
66+ zeroOrMoreSpaces() : DateRegExBuilder {
67+ this.regexString += DateRegExBuilder.ZERO_OR_MORE_SPACES;
68+ return this;
69+ }
70+
71+ /**
72+ * Adds a match group for zero or more whitespace tokens.
73+ * @returns {DateRegExBuilder}
74+ */
75+ oneOrMoreSpaces() : DateRegExBuilder {
76+ this.regexString += DateRegExBuilder.ONE_OR_MORE_SPACES;
77+ return this;
78+ }
79+
80+ SLASH_DELIMITOR() : DateRegExBuilder {
81+ this.regexString += "\\/";
82+ return this;
83+ }
84+
85+ /**
86+ * Adds all month full name and short names to the regular expression.
87+ * @returns {DateRegExBuilder}
88+ */
89+ monthNameCaptureGroup() : DateRegExBuilder {
90+ this.regexString += "(january|february|march|april|may|june|july|august|september|october|november|december|jan|feb|mar|apr|jun|jul|aug|sep|oct|nov|dec)";
91+ return this;
92+ }
93+
94+ /**
95+ * Adds month digit to the regular expression.
96+ * @returns {DateRegExBuilder}
97+ */
98+ MM() : DateRegExBuilder {
99+ this.regexString += "([1-9]|0[1-9]|1[0-2])";
100+ return this;
101+ }
102+
103+ /**
104+ *
105+ * @returns {DateRegExBuilder}
106+ */
107+ DD() : DateRegExBuilder {
108+ this.regexString += "([1-9]|[0-2][0-9]|3[0-1])";
109+ return this;
110+ }
111+
112+ YYYY() : DateRegExBuilder {
113+ this.regexString += "(([0-9][0-9][0-9][0-9])|([1-9][0-9][0-9]))";
114+ return this;
115+ }
116+
117+ /**
118+ * Builds the regular expression.
119+ * @returns {RegExp} Built up string as a regular expression.
120+ */
121+ build() : RegExp {
122+ return new RegExp(this.regexString);
123+ }
124+}
125+
126+
127 export {
128 ArgsChecker,
129 CriteriaFunctionFactory,
130+ DateRegExBuilder,
131 Filter,
132 Serializer,
133 TypeCaster