spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
Adding timestamp capture group to last regex, documenting DateRegExBuilder
author
Ben Vogt <[email protected]>
date
2017-04-01 18:22:06
stats
3 file(s) changed, 110 insertions(+), 15 deletions(-)
files
src/RawFormulas/Date.ts
src/RawFormulas/Utils.ts
tests/DateFormulasTest.ts
  1diff --git a/src/RawFormulas/Date.ts b/src/RawFormulas/Date.ts
  2index ef7d362..879781d 100644
  3--- a/src/RawFormulas/Date.ts
  4+++ b/src/RawFormulas/Date.ts
  5@@ -46,36 +46,36 @@ var DATE = function (...values) {
  6 const YEAR_MONTHDIG_DAY = DateRegExBuilder.DateRegExBuilder()
  7   .start()
  8   .OPTIONAL_DAYNAME().OPTIONAL_COMMA().YYYY().FLEX_DELIMITER().MM().FLEX_DELIMITER().DD_W_SPACE().OPTIONAL_TIMESTAMP_CAPTURE_GROUP()
  9-  .simpleEnd()
 10+  .end()
 11   .build();
 12 const MONTHDIG_DAY_YEAR = DateRegExBuilder.DateRegExBuilder()
 13   .start()
 14   .OPTIONAL_DAYNAME().OPTIONAL_COMMA().MM().FLEX_DELIMITER().DD().FLEX_DELIMITER().YYYY14_W_SPACE().OPTIONAL_TIMESTAMP_CAPTURE_GROUP()
 15-  .simpleEnd()
 16+  .end()
 17   .build();
 18 const DAY_MONTHNAME_YEAR = DateRegExBuilder.DateRegExBuilder()
 19   .start()
 20   .OPTIONAL_DAYNAME().OPTIONAL_COMMA().DD().FLEX_DELIMITER().MONTHNAME().FLEX_DELIMITER().YYYY14_W_SPACE().OPTIONAL_TIMESTAMP_CAPTURE_GROUP()
 21-  .simpleEnd()
 22+  .end()
 23   .build();
 24 const YEAR_MONTHDIG = DateRegExBuilder.DateRegExBuilder()
 25   .start()
 26   .OPTIONAL_DAYNAME().OPTIONAL_COMMA().YYYY14().FLEX_DELIMITER().MM_W_SPACE().OPTIONAL_TIMESTAMP_CAPTURE_GROUP()
 27-  .simpleEnd()
 28+  .end()
 29   .build();
 30 const MONTHDIG_YEAR = DateRegExBuilder.DateRegExBuilder()
 31   .start()
 32   .OPTIONAL_DAYNAME().OPTIONAL_COMMA().MM().FLEX_DELIMITER().YYYY14_W_SPACE().OPTIONAL_TIMESTAMP_CAPTURE_GROUP()
 33-  .simpleEnd()
 34+  .end()
 35   .build();
 36 const YEAR_MONTHNAME = DateRegExBuilder.DateRegExBuilder()
 37   .start()
 38   .OPTIONAL_DAYNAME().OPTIONAL_COMMA().YYYY14().FLEX_DELIMITER().MONTHNAME_W_SPACE().OPTIONAL_TIMESTAMP_CAPTURE_GROUP()
 39-  .simpleEnd()
 40+  .end()
 41   .build();
 42 const MONTHNAME_YEAR = DateRegExBuilder.DateRegExBuilder()
 43   .start()
 44-  .OPTIONAL_DAYNAME().OPTIONAL_COMMA().MONTHNAME().FLEX_DELIMITER().YYYY14()
 45+  .OPTIONAL_DAYNAME().OPTIONAL_COMMA().MONTHNAME().FLEX_DELIMITER().YYYY14_W_SPACE().OPTIONAL_TIMESTAMP_CAPTURE_GROUP()
 46   .end()
 47   .build();
 48 
 49@@ -184,6 +184,9 @@ var DATEVALUE = function (...values) : number {
 50   if (m === undefined) {
 51     var matches = dateString.match(MONTHNAME_YEAR);
 52     if (matches && matches.length >= 6) {
 53+      if (matches[6] !== undefined) {
 54+        console.log("MONTHNAME_YEAR matched timestamp", matches[6]);
 55+      }
 56       var years = parseInt(matches[5]);
 57       var monthName = matches[3];
 58       m = createMoment(years, monthName, 0);
 59diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
 60index 4e71f46..262431f 100644
 61--- a/src/RawFormulas/Utils.ts
 62+++ b/src/RawFormulas/Utils.ts
 63@@ -375,92 +375,162 @@ class DateRegExBuilder {
 64     return new DateRegExBuilder();
 65   }
 66 
 67+  /**
 68+   * Start the regular expression builder by matching the start of a line and zero or more spaces.
 69+   * @returns {DateRegExBuilder} builder
 70+   */
 71   start() : DateRegExBuilder {
 72     this.regexString += "^" + DateRegExBuilder.ZERO_OR_MORE_SPACES;
 73     return this;
 74   }
 75 
 76-  end() : DateRegExBuilder {
 77-    this.regexString += "\\s*$";
 78-    return this;
 79-  }
 80-
 81-  simpleEnd(): DateRegExBuilder {
 82+  /**
 83+   * End the regular expression builder by matching the end of the line.
 84+   * @returns {DateRegExBuilder} builder
 85+   */
 86+  end(): DateRegExBuilder {
 87     this.regexString += "$";
 88     return this;
 89   }
 90 
 91   /**
 92-   * Adds all month full name and short names to the regular expression.
 93-   * @returns {DateRegExBuilder}
 94+   * Capture all month full name and short names to the regular expression.
 95+   * @returns {DateRegExBuilder} builder
 96    */
 97   MONTHNAME() : DateRegExBuilder {
 98     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)";
 99     return this;
100   }
101 
102+  /**
103+   * Capture all month full name and short names to the regular expression, in addition to any followed by one or more
104+   * spaces.
105+   * @returns {DateRegExBuilder} builder
106+   * @constructor
107+   */
108   MONTHNAME_W_SPACE() : DateRegExBuilder {
109     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|january\\s+|february\\s+|march\\s+|april\\s+|may\\s+|june\\s+|july\\s+|august\\s+|september\\s+|october\\s+|november\\s+|december\\s+|jan\\s+|feb\\s+|mar\\s+|apr\\s+|jun\\s+|jul\\s+|aug\\s+|sep\\s+|oct\\s+|nov\\s+|dec\\s+)";
110     return this;
111   }
112 
113+  /**
114+   * Add capture group for optionally capturing day names.
115+   * @returns {DateRegExBuilder} builder
116+   * @constructor
117+   */
118   OPTIONAL_DAYNAME() : DateRegExBuilder {
119     this.regexString += "(sunday|monday|tuesday|wednesday|thursday|friday|saturday|sun|mon|tue|wed|thu|fri|sat)?";
120     return this;
121   }
122 
123+  /**
124+   * Add capture group for optionally capturing a comma followed by one or more spaces.
125+   * @returns {DateRegExBuilder} builder
126+   * @constructor
127+   */
128   OPTIONAL_COMMA() : DateRegExBuilder {
129     this.regexString += "(,?\\s+)?";
130     return this;
131   }
132 
133+  /**
134+   * Add capture group for capturing month digits between 01 and 12, inclusively.
135+   * @returns {DateRegExBuilder} builder
136+   * @constructor
137+   */
138   MM() : DateRegExBuilder {
139     this.regexString += "([1-9]|0[1-9]|1[0-2])";
140     return this;
141   }
142 
143+  /**
144+   * Add capture group for capturing month digits between 01 and 12, inclusively, in addition to any followed by one or
145+   * more spaces.
146+   * @returns {DateRegExBuilder} builder
147+   * @constructor
148+   */
149   MM_W_SPACE() : DateRegExBuilder {
150     this.regexString += "([1-9]|0[1-9]|1[0-2]|[1-9]\\s+|0[1-9]\\s+|1[0-2]\\s+)";
151     return this;
152   }
153 
154+  /**
155+   * Add capture group for capturing day digits between 01 and 31, inclusively.
156+   * @returns {DateRegExBuilder} builder
157+   * @constructor
158+   */
159   DD() : DateRegExBuilder {
160     this.regexString += "(0?[0-9]|1[0-9]|2[0-9]|3[0-1])";
161     return this;
162   }
163 
164+  /**
165+   * Add capture group for capturing day digits between 01 and 31, inclusively, in addition to any followed by one or
166+   * more spaces.
167+   * @returns {DateRegExBuilder} builder
168+   * @constructor
169+   */
170   DD_W_SPACE() : DateRegExBuilder {
171     this.regexString += "(0?[0-9]|1[0-9]|2[0-9]|3[0-1]|0?[0-9]\\s+|1[0-9]\\s+|2[0-9]\\s+|3[0-1]\\s+)";
172     return this;
173   }
174 
175+  /**
176+   * Add capture group for capturing 4 digits or 3 digits starting with 0-9.
177+   * @returns {DateRegExBuilder} builder
178+   * @constructor
179+   */
180   YYYY() : DateRegExBuilder {
181     this.regexString += "([0-9]{4}|[1-9][0-9][0-9])";
182     return this;
183   }
184 
185+  /**
186+   * Add capture group for capturing 1 through 4 digits.
187+   * @returns {DateRegExBuilder} builder
188+   * @constructor
189+   */
190   YYYY14() : DateRegExBuilder {
191     this.regexString += "([0-9]{1,4})";
192     return this;
193   }
194 
195+  /**
196+   * Add capture group for capturing 1 through 4 digits, in addition to any followed by one or more spaces.
197+   * @returns {DateRegExBuilder} builder
198+   * @constructor
199+   */
200   YYYY14_W_SPACE() : DateRegExBuilder {
201     this.regexString += "([0-9]{1,4}|[0-9]{1,4}\\s+)";
202     return this;
203   }
204 
205+  /**
206+   * Add capture group for a flexible delimiter, including ", ", " ", ".", "\", "-".
207+   * @returns {DateRegExBuilder} builder
208+   * @constructor
209+   */
210   FLEX_DELIMITER() : DateRegExBuilder {
211     this.regexString += "(,?\\s+|\\s*-?\\.?-?\\/?\\s*)";
212     return this;
213   }
214 
215+  /**
216+   * Add a capture group for capturing timestamps including: "10am", "10:10", "10:10pm", "10:10:10", "10:10:10am", along
217+   * with zero or more spaces after semi colons, AM or PM, and unlimited number of digits per unit.
218+   * @returns {DateRegExBuilder} builder
219+   * @constructor
220+   */
221   OPTIONAL_TIMESTAMP_CAPTURE_GROUP() : DateRegExBuilder {
222     this.regexString += "((\\s+[0-9]+\\s*am\\s*$|[0-9]+\\s*pm\\s*$)|(\\s+[0-9]+:\\s*[0-9]+\\s*$)|(\\s+[0-9]+:\\s*[0-9]+\\s*am\\s*$|\\s+[0-9]+:\\s*[0-9]+\\s*pm\\s*$)|(\\s+[0-9]+:\\s*[0-9]+:\\s*[0-9]+\\s*$)|(\\s+[0-9]+:\\s*[0-9]+:\\s*[0-9]+\\s*am\\s*$|[0-9]+:\\s*[0-9]+:\\s*[0-9]+\\s*pm\\s*$))?";
223     return this;
224   }
225 
226+  /**
227+   * Build the regular expression and ignore case.
228+   * @returns {RegExp}
229+   */
230   build() : RegExp {
231-    // Always ignore case.
232     return new RegExp(this.regexString, 'i');
233   }
234 }
235diff --git a/tests/DateFormulasTest.ts b/tests/DateFormulasTest.ts
236index 2864ac4..db8fdea 100644
237--- a/tests/DateFormulasTest.ts
238+++ b/tests/DateFormulasTest.ts
239@@ -389,7 +389,17 @@ assertEquals(DATEVALUE("January, 2017"), 42736);
240 catchAndAssertEquals(function() {
241   DATEVALUE("January,2017");
242 }, ERRORS.VALUE_ERROR);
243-
244+// timestamp test
245+assertEquals(DATEVALUE("January-2017 10am"), 42736); // TODO: come back to these. right now just testing to make sure they don't break anything.
246+assertEquals(DATEVALUE("January-2017 10:10"), 42736);
247+assertEquals(DATEVALUE("January-2017 10:10am"), 42736);
248+assertEquals(DATEVALUE("January-2017 10:10:10"), 42736);
249+assertEquals(DATEVALUE("January-2017 10:10:10am"), 42736);
250+assertEquals(DATEVALUE("January-2017  10  am"), 42736);
251+assertEquals(DATEVALUE("January-2017 10: 10 "), 42736);
252+assertEquals(DATEVALUE("January-2017 10: 10 pm"), 42736);
253+assertEquals(DATEVALUE("January-2017 10: 10: 10"), 42736);
254+assertEquals(DATEVALUE("January-2017  101120: 10: 10    am  "), 42736);
255 
256 
257