If you are looking for a matching of all incidents of a regexp without capture groups--which the original poster was not, but which may be desired by those landing here from Google--you want to use JavaScript's String.prototype.match
along with a g
lobal flag on the RegExp:
ruby -e "p '12h 37m'.scan /\d+/"
#=> ["12", "37"]
node -e "console.log('12h 37m'.match(/\d+/g))"
// [ '12', '37' ]
If capture groups are important, then the String.prototype.matchAll
method may instead be desired:
console.log(Array.from('12h 37m'.matchAll(/(\d+)(.)/g)))
// [
// [ '12h', '12', 'h', index: 0, input: '12h 37m', groups: undefined ],
// [ '37m', '37', 'm', index: 4, input: '12h 37m', groups: undefined ]
// ]
The results of this can be used for functional transformation by extracting the non-zero numerical entries from each result using slice()
:
Array.from('12h 37m'.matchAll(/(\d+)(.)/g))).flatMap( m => m.slice(1) )
// [ '12', 'h', '37', 'm' ]
Wrapping this up as a convenient extension on the prototype as others have done:
if (!String.prototype.scan) String.prototype.scan = function(re) {
if (!re.global) {
throw new Error("String#scan requires RegExp with global (g) flag")
}
return Array.from(this.matchAll(re))
.flatMap(m => m.length > 1 ? m.slice(1) : m[0])
}
const str = '12h 37m'
console.log(str.scan(/\d+/g))
// [ '12', '37' ]
console.log(str.scan(/(\d+)(.)/g))
// [ '12', 'h', '37', 'm' ]