@@ -120,74 +120,42 @@ export class StringUtil implements IStringUtil {
120120 }
121121
122122 /**
123- * Returns all RegExp matches and capture groups for the given regular expression and string, optionally starting from a specific character .
124- * @param {RegExp } regex
123+ * Returns all index matches of the provided Regular Expression on the provided string, optionally starting from a specific index .
124+ * @param {RegExp } regexp
125125 * @param {string } str
126- * @param {number } startingFrom
127- * @returns {string[] [] }
126+ * @param {number } [from=0]
127+ * @returns {number [] }
128128 */
129- public allMatchesAndCaptureGroupsOf ( regex : RegExp , str : string , startingFrom : number = 0 ) : string [ ] [ ] {
130- if ( startingFrom < 0 || startingFrom > str . length ) throw new RangeError ( `Given 'startingFrom' value: ${ startingFrom } is out of bounds!` ) ;
131- const matches : string [ ] [ ] = [ ] ;
132- let match : RegExpExecArray | null ;
133- let currentString = str ;
134- while ( ( match = regex . exec ( currentString ) ) != null ) {
135- if ( match . index >= startingFrom ) matches . push ( match . slice ( 1 ) ) ;
136- currentString = currentString . slice ( currentString . indexOf ( match [ 1 ] ) + match [ 1 ] . length ) ;
137- }
138- return matches ;
129+ public allIndexesOf ( str : string , regexp : RegExp , from : number = 0 ) : number [ ] {
130+ return this . matchAll ( str , regexp , from ) . map ( match => match . index ) ;
139131 }
140132
141133 /**
142- * Returns all RegExp matches of the given regular expression on the given string, optionally starting from a specific index.
143- * @param {RegExp } regex
134+ * Matches all occurrences of the given RegExp, including capture groups, globally. Supports both global RegExps and non-global RegExps
144135 * @param {string } str
145- * @param {number } startingFrom
146- * @returns {string[] }
136+ * @param {RegExp } regexp
137+ * @param {number } [from=0]
138+ * @returns {RegExpExecArray[] }
147139 */
148- public allMatchesOf ( regex : RegExp , str : string , startingFrom : number = 0 ) : string [ ] {
149- if ( startingFrom < 0 || startingFrom > str . length ) throw new RangeError ( `Given 'startingFrom' value: ${ startingFrom } is out of bounds!` ) ;
150- const matches : string [ ] = [ ] ;
151- let match : RegExpExecArray | null ;
152- let currentString = str ;
153- while ( ( match = regex . exec ( currentString ) ) != null ) {
154- if ( match . index >= startingFrom ) matches . push ( match [ 1 ] ) ;
155- currentString = currentString . slice ( currentString . indexOf ( match [ 1 ] ) + match [ 1 ] . length ) ;
140+ public matchAll ( str : string , regexp : RegExp , from : number = 0 ) : RegExpExecArray [ ] {
141+ let flags = regexp . flags ;
142+ if ( ! flags . includes ( "g" ) ) {
143+ flags += "g" ;
156144 }
157- return matches ;
158- }
159145
160- /**
161- * Returns all index matches of the provided Regular Expression on the provided string, optionally starting from a specific index.
162- * @param {RegExp } regex
163- * @param {string } str
164- * @param {number } startingFrom
165- * @returns {number[] }
166- */
167- public allIndexesOf ( regex : RegExp , str : string , startingFrom : number = 0 ) : number [ ] {
168- if ( startingFrom < 0 || startingFrom > str . length ) throw new RangeError ( `Given 'startingFrom' value: ${ startingFrom } is out of bounds!` ) ;
169- const matches : number [ ] = [ ] ;
170- let match : RegExpExecArray | null ;
171- while ( ( match = regex . exec ( str ) ) != null ) {
172- if ( match . index >= startingFrom ) matches . push ( match . index ) ;
173- }
174- return matches ;
175- }
146+ // Normalize the regular expression and make sure it *does* include the Global ('g') flag
147+ const normalizedRegExp = new RegExp ( regexp , flags ) ;
176148
177- /**
178- * Returns all match objects of the provided regular expression on the provided string, optionally starting from a specific index.
179- * @param {RegExp } regex
180- * @param {string } str
181- * @param {number } startingFrom
182- * @returns {RegExpMatchArray[] }
183- */
184- public allMatchObjectsOf ( regex : RegExp , str : string , startingFrom : number = 0 ) : RegExpMatchArray [ ] {
185- if ( startingFrom < 0 || startingFrom > str . length ) throw new RangeError ( `Given 'startingFrom' value: ${ startingFrom } is out of bounds!` ) ;
186149 const matches : RegExpExecArray [ ] = [ ] ;
187- let match : RegExpExecArray | null ;
188- while ( ( match = regex . exec ( str ) ) != null ) {
189- if ( match . index >= startingFrom ) matches . push ( match ) ;
150+
151+ while ( true ) {
152+ const match = normalizedRegExp . exec ( str ) ;
153+ if ( match == null ) break ;
154+ if ( match . index >= from ) {
155+ matches . push ( match ) ;
156+ }
190157 }
158+
191159 return matches ;
192160 }
193161
@@ -266,7 +234,9 @@ export class StringUtil implements IStringUtil {
266234 }
267235
268236 // Remove any kind of whitespace.
269- return str . replace ( / [ \n \t \r ] / g, "" ) . replace ( / & n b s p ; / , "" ) ;
237+ return str
238+ . replace ( / [ \n \t \r ] / g, "" )
239+ . replace ( / & n b s p ; / , "" ) ;
270240 }
271241
272242 /**
@@ -275,7 +245,16 @@ export class StringUtil implements IStringUtil {
275245 * @returns {boolean }
276246 */
277247 public containsWhitespace ( str : string ) : boolean {
278- return / ( & n b s p ; | \t | \n | \r | \s ) / . test ( str ) ;
248+ return str . length !== this . removeWhitespace ( str ) . length ;
249+ }
250+
251+ /**
252+ * Returns true if the given string contains nothing but whitespace
253+ * @param {string } str
254+ * @returns {boolean }
255+ */
256+ public containsOnlyWhitespace ( str : string ) : boolean {
257+ return this . removeWhitespace ( str ) . length === 0 ;
279258 }
280259
281260 /**
@@ -295,27 +274,5 @@ export class StringUtil implements IStringUtil {
295274 }
296275 return local ;
297276 }
298-
299- /**
300- * Slices a string from a specific index or string expression.
301- * @param {string } str
302- * @param {number | string } from
303- * @returns {string }
304- */
305- public takeFrom ( str : string , from : number | string ) : string {
306- const index = typeof from === "number" ? from : str . indexOf ( from ) ;
307- return str . slice ( index ) ;
308- }
309-
310- /**
311- * Slices a string from after the string expression.
312- * @param {string } str
313- * @param {string } from
314- * @returns {string }
315- */
316- public takeFromAfter ( str : string , from : string ) : string {
317- return this . takeFrom ( str , from ) . slice ( from . length ) ;
318- }
319-
320277}
321278
0 commit comments