ECMAScript
ECMAScript

Reputation: 4649

What is the best way to extract the numbers out of this text

P1W2DT6H21M32S

Wondering the best way to extract the numbers out of here.

W = Weeks
D = Days
H = Hours
M = Minutes
S = Seconds

Something like this only works for M and S, and it seems like I'm not doing it right.

    var time = "PT44M7S";
    var minutes = time.substring(2, time.indexOf("M"));
    var seconds = time.split("M")[1].substring(0, time.split("M")[1].indexOf("S"));

Upvotes: 0

Views: 97

Answers (6)

Brian Sexton
Brian Sexton

Reputation: 67

How about dropping the non-digits on the ends then splitting on the remaining non-digit chunks?

var justNumbers = "P1W2DT6H21M32S".replace(/^\D|\D$/g, "").split(/\D+/);

That should give you a nice clean array of numbers.

You can add the following if you want to store the resulting array values in a more easily understandable object:

var keys = ["weeks", "days", "hours", "minutes", "seconds"];

var time = {};

for (var k = 0; k < keys.length; k++) {
    time[keys[k]] = justNumbers[k];
}

JSFiddle: http://jsfiddle.net/briansexton/AXh7F/

Upvotes: 0

Marco Bonelli
Marco Bonelli

Reputation: 69377

I don't know why there are those two letters: P and T. But since they are there you need to remove them. So you can split the text and then remove the empty strings from the array you just obtained:

var time = 'P1W2DT6H21M32S';

time = time.split(/[A-Z]/);
time = time.join(',').replace(/,,/g, ',').substr(1).slice(0, -1).split(',');

> ["1", "2", "6", "21", "32"]

Upvotes: 0

Barmar
Barmar

Reputation: 782148

var timePeriod = {};
var str = 'P1W2DT6H21M32S';
var re = /(\d+)([WDHMS])/g;
while (result = re.exec(str)) {
    timePeriod[result[2]] = parseInt(result[1], 10);
}
console.log(timePeriod);

should produce:

{ W: 1, D: 2, H: 6, M: 21, S: 32 }

Upvotes: 2

user2864740
user2864740

Reputation: 61975

Consider a regular expression such as this:

/P(?:(\d+)W)?(?:(\d+)D)?T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/

Then the values would be in the groups 1=W, 2=D, 3=H, 4=M, 5=S.

The advantage of something like this over a plain split is that it will still work correctly if any fields have been omitted - as long as the supplied fields remain in order.

Upvotes: 0

OnlineCop
OnlineCop

Reputation: 4069

Using a regular expression, you could "optionally capture" each group and then recall them as needed:

(?:(\d+)W)?(?:(\d+)D?)?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?

Example

var re = /(?:(\d+)W)?(?:(\d+)D?)?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/gm; 
var str = 'P1W2DT6H21M32S\nPT44M7S\n';
var subst = 'Week: $1\nDay: $2\nHour: $3\nMinute: $4\nSecond: $5\n'; 
var result = str.replace(re, subst);

Upvotes: 1

Evan Trimboli
Evan Trimboli

Reputation: 30092

You could split on letters, although you'll get leading and trailing spaces in the array:

'P1W2DT6H21M32S'.split(/[A-Z]/)

Upvotes: 1

Related Questions