1

I am trying to extract year, month and days data from the string 1 year, 5 months and 4 days.

Similarly, I want to be able to convert 1/2/4 into 1 year, 2 months and 4 days

In both case, I would like to handle day vs days or remove days if they are 0.

What is the best way to do this?

1
  • 1
    Read about javascript regular expression functions, i.e. String.match(). Commented Nov 11, 2015 at 5:38

1 Answer 1

2

You can use replace() with callback

function format(str) {
  return str.replace(/(\d+)\/(\d+)\/(\d+)/, function(m, m1, m2, m3) {
    var s = [];
    if (m1 != 0)
      s.push(m1 + (m1 == 1 ? ' year' : ' years'));
    if (m2 != 0)
      s.push(m2 + (m2 == 1 ? ' month' : ' months'))
    if (m3 != 0)
      s.push(m3 + (m3 == 1 ? ' day' : ' days'))
    if (s.length == 3)
      return s[0] + ', ' + s[1] + ' and ' + s[2];
    else if (s.length == 2)
      return s[0] + ' and ' + s[1];
    else
      return s[0];
  })
}
document.write(format('1/2/4') +
  '<br>' + format('1/2/0') +
  '<br>' + format('0/2/0') +
  '<br>' + format('1/2/4') +
  '<br>' + format('2/2/4') +
  '<br>' + format('1/21/0') +
  '<br>' + format('0/2/1') +
  '<br>' + format('1/1/1'));

Regex explanation here

Regular expression visualization

UPDATE : Reverse can be done as following using replace() and join()

function formatRev(str) {
  return str.replace(/^(?:(\d+)\s+(\w+)\s*,\s*)?(\d+)\s+(\w+)(?:\s+and\s+(\d+)\s+(\w+))?$/ig, function(m, m1, m2, m3, m4, m5, m6) {
    var s = [0, 0, 0];
    s[extract(m2)] = m1;
    s[extract(m4)] = m3;
    s[extract(m6)] = m5;
    return s.join('/');
  })
}

function extract(str) {
  if (/year/.test(str))
    return 0;
  else if (/month/.test(str))
    return 1;
  else if (/day/.test(str))
    return 2;
  else
    return null;
}

document.write(formatRev('5 years and 4 days') +
  '<br>' + formatRev('1 year and 2 months') +
  '<br>' + formatRev('2 months') +
  '<br>' + formatRev('1 year, 2 months and 4 days')
);

Regex explanation here

Regular expression visualization

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks :D What's the best way to extract it in reverse? Eg: 1 year and 3 days. I am currently using split and lots of if-else , anything more elegant you can suggest?
@SudhanshuShekhar Try (?:(\d+) years?)?\s*(?:(\d+) months?)?\s*(?:(\d+) days?)? Not sure if this will help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.