spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← All files
name: src/Utilities/DateRegExBuilder.ts
-rw-r--r--
7281
  1/**
  2 * Build a regular expression step by step, to make it easier to build and read the resulting regular expressions.
  3 */
  4class DateRegExBuilder {
  5  private regexString = "";
  6  private static ZERO_OR_MORE_SPACES = "\\s*";
  7
  8  static DateRegExBuilder() : DateRegExBuilder {
  9    return new DateRegExBuilder();
 10  }
 11
 12  /**
 13   * Start the regular expression builder by matching the start of a line and zero or more spaces.
 14   * @returns {DateRegExBuilder} builder
 15   */
 16  start() : DateRegExBuilder {
 17    this.regexString += "^" + DateRegExBuilder.ZERO_OR_MORE_SPACES;
 18    return this;
 19  }
 20
 21  /**
 22   * End the regular expression builder by matching the end of the line.
 23   * @returns {DateRegExBuilder} builder
 24   */
 25  end(): DateRegExBuilder {
 26    this.regexString += "$";
 27    return this;
 28  }
 29
 30  /**
 31   * Capture all month full name and short names to the regular expression.
 32   * @returns {DateRegExBuilder} builder
 33   */
 34  MONTHNAME() : DateRegExBuilder {
 35    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)";
 36    return this;
 37  }
 38
 39  /**
 40   * Capture all month full name and short names to the regular expression, in addition to any followed by one or more
 41   * spaces.
 42   * @returns {DateRegExBuilder} builder
 43   * @constructor
 44   */
 45  MONTHNAME_W_SPACE() : DateRegExBuilder {
 46    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+)";
 47    return this;
 48  }
 49
 50  /**
 51   * Add capture group for optionally capturing day names.
 52   * @returns {DateRegExBuilder} builder
 53   * @constructor
 54   */
 55  OPTIONAL_DAYNAME() : DateRegExBuilder {
 56    this.regexString += "(sunday|monday|tuesday|wednesday|thursday|friday|saturday|sun|mon|tue|wed|thu|fri|sat)?";
 57    return this;
 58  }
 59
 60  /**
 61   * Add capture group for optionally capturing a comma followed by one or more spaces.
 62   * @returns {DateRegExBuilder} builder
 63   * @constructor
 64   */
 65  OPTIONAL_COMMA() : DateRegExBuilder {
 66    this.regexString += "(,?\\s+)?";
 67    return this;
 68  }
 69
 70  /**
 71   * Add capture group for capturing month digits between 01 and 12, inclusively.
 72   * @returns {DateRegExBuilder} builder
 73   * @constructor
 74   */
 75  MM() : DateRegExBuilder {
 76    this.regexString += "([1-9]|0[1-9]|1[0-2])";
 77    return this;
 78  }
 79
 80  /**
 81   * Add capture group for capturing month digits between 01 and 12, inclusively, in addition to any followed by one or
 82   * more spaces.
 83   * @returns {DateRegExBuilder} builder
 84   * @constructor
 85   */
 86  MM_W_SPACE() : DateRegExBuilder {
 87    this.regexString += "([1-9]|0[1-9]|1[0-2]|[1-9]\\s+|0[1-9]\\s+|1[0-2]\\s+)";
 88    return this;
 89  }
 90
 91  /**
 92   * Add capture group for capturing day digits between 01 and 31, inclusively.
 93   * @returns {DateRegExBuilder} builder
 94   * @constructor
 95   */
 96  DD() : DateRegExBuilder {
 97    this.regexString += "(0?[0-9]|1[0-9]|2[0-9]|3[0-1])";
 98    return this;
 99  }
100
101  /**
102   * Add capture group for capturing day digits between 01 and 31, inclusively, in addition to any followed by one or
103   * more spaces.
104   * @returns {DateRegExBuilder} builder
105   * @constructor
106   */
107  DD_W_SPACE() : DateRegExBuilder {
108    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+)";
109    return this;
110  }
111
112  /**
113   * Add capture group for capturing 4 digits or 3 digits starting with 0-9.
114   * @returns {DateRegExBuilder} builder
115   * @constructor
116   */
117  YYYY() : DateRegExBuilder {
118    this.regexString += "([0-9]{4}|[1-9][0-9][0-9])";
119    return this;
120  }
121
122  /**
123   * Add capture group for capturing 1 through 4 digits.
124   * @returns {DateRegExBuilder} builder
125   * @constructor
126   */
127  YYYY14() : DateRegExBuilder {
128    this.regexString += "([0-9]{1,4})";
129    return this;
130  }
131
132  /**
133   * Add capture group for capturing 1 through 4 digits, in addition to any followed by one or more spaces.
134   * @returns {DateRegExBuilder} builder
135   * @constructor
136   */
137  YYYY14_W_SPACE() : DateRegExBuilder {
138    this.regexString += "([0-9]{1,4}|[0-9]{1,4}\\s+)";
139    return this;
140  }
141
142  YYYY2_OR_4_W_SPACE() : DateRegExBuilder {
143    this.regexString += "([0-9]{2}|[0-9]{4}|[0-9]{2}\\s+|[0-9]{4}\\s+)";
144    return this;
145  }
146
147  /**
148   * Add capture group for a flexible delimiter, including ", ", " ", ". ", "\", "-".
149   * @returns {DateRegExBuilder} builder
150   * @constructor
151   */
152  FLEX_DELIMITER() : DateRegExBuilder {
153    // this.regexString += "(,?\\s+|\\s*-?\\.?-?\\/?\\s+)";// close to being right
154    this.regexString += "(,?\\s+|\\s*\\.\\s+|\\s*-\\s*|\\s*\\/\\s*)";
155    return this;
156  }
157
158  /**
159   * Add capture group for a flexible delimiter, including ", ", " ", ".", "\", "-". Different from FLEX_DELIMITER
160   * in that it will match periods with zero or more spaces on either side.
161   * For reference: https://regex101.com/r/q1fp1z/1/
162   * @returns {DateRegExBuilder} builder
163   * @constructor
164   */
165  FLEX_DELIMITER_LOOSEDOT() : DateRegExBuilder {
166    // this.regexString += "(,?\\s+|\\s*-?\\.?-?\\/?\\s+)";// close to being right
167    this.regexString += "(,?\\s+|\\s*\\.\\s*|\\s*-\\s*|\\s*\\/\\s*)";
168    return this;
169  }
170
171  /**
172   * Add an optional capture group for capturing timestamps including: "10am", "10:10", "10:10pm", "10:10:10",
173   * "10:10:10am", along with zero or more spaces after semi colons, AM or PM, and unlimited number of digits per unit.
174   * @returns {DateRegExBuilder} builder
175   * @constructor
176   */
177  OPTIONAL_TIMESTAMP_CAPTURE_GROUP() : DateRegExBuilder {
178    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*$))?";
179    return this;
180  }
181
182
183  /**
184   * Add a capture group for capturing timestamps including: "10am", "10:10", "10:10pm", "10:10:10",
185   * "10:10:10am", along with zero or more spaces after semi colons, AM or PM, and unlimited number of digits per unit.
186   * See https://regex101.com/r/0bmj5n/1/ for more information of 9-digit maximum. One series, "12:00001989198298am",
187   * has a maximum of 10 digits: "0*(?:[1-9]{1}[0-9]{0,9})?"
188   * @returns {DateRegExBuilder} builder
189   * @constructor
190   */
191  TIMESTAMP_UNITS_CAPTURE_GROUP() : DateRegExBuilder {
192    this.regexString += "(\\s*(0*(?:[1-9]{1}[0-9]{0,8})?)()()\\s*(am|pm)\\s*$)|(\\s*(0*(?:[1-9]{1}[0-9]{0,8})?):\\s*(0*(?:[1-9]{1}[0-9]{0,8})?)()()\\s*$)|(\\s*((0*(?:[1-9]{1}[0-9]{0,8})?):\\s*(0*(?:[1-9]{1}[0-9]{0,9})?)()\\s*(am|pm))\\s*$)|(\\s*((0*(?:[1-9]{1}[0-9]{0,8})?):\\s*(0*(?:[1-9]{1}[0-9]{0,8})?):\\s*(0*(?:[1-9]{1}[0-9]{0,8})?)())\\s*$)|(\\s*((0*(?:[1-9]{1}[0-9]{0,8})?):\\s*(0*(?:[1-9]{1}[0-9]{0,8})?):\\s*(0*(?:[1-9]{1}[0-9]{0,8})?)\\s*(am|pm))\\s*$)";
193    return this;
194  }
195
196  /**
197   * Build the regular expression and ignore case.
198   * @returns {RegExp}
199   */
200  build() : RegExp {
201    return new RegExp(this.regexString, 'i');
202  }
203}
204
205export {
206  DateRegExBuilder
207}