Can a javascript regular expression help clean up these odd formats?

Objective: Clean up/format value in javascript variable zheight_feet_and_inches before attempting to use it for calculations:
         
      Desired format  5' 4"   (This is what my calculation code expects.  It works properly when the numbers are received in this format.)

      Unexpected formats examples:  
         4' .5"
         5' 5.5"
         5' 11.5"
         5' 5.354"

(Numbers come from an external system over which I have no control.)    

I know I could write several if statements and string functions to clean these up,
but I know just  enough about regular expressions to think one might be useful here and save me
writing a lot of code.   But I have no idea which one or even how to write them in javascript.  

Can someone help me out here?
codefingerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Steve BinkCommented:
What do you want to do with the rounded portions?

This should be pretty simple, if the notations are consistent.  Split the string by the apostrophe, then remove the last character of the inches portion.  Convert both to integers, then reform the string.

Here's a sample I whipped up for you:
// set up the values to convert
var a=['4\' .5"','5\' 5.5"', '5\' 11.5"','5\' 5.354"']

// here's the function
function pretty($x) {
  var $y = $x.split("'"),
      $ft = parseInt($y[0]),
      $in = parseInt($y[1].trim().substring($y[1]-1)) || '0';
  return $ft + "'" + $in + '"';
}

// run it
a.forEach(function(v,k){console.log(pretty(v));})

/* output:
4'0"
5'5"
5'11"
5'5"
*/

Open in new window

2
codefingerAuthor Commented:
I found that only one format actually causes problems with the subsequent calculation:

4' .5"

I was having a lot of trouble understanding this line....

$in = parseInt($y[1].trim().substring($y[1]-1)) || '0';

so I broke it down....

var splitit = zheight_feet_and_inches.split("'");
var inchside1 = splitit[1];
var inchside2 = inchside1.trim();
var inchside3  = inchside2.substring(inchside2 - 1);
var inchside4 = parseInt(inchside3);

.....and found I was always getting an NaN value in inchside4 when this was called

parseInt(inchside4)    --   The value of inchside3 at this point is .5".

Can you help me figure out what I am doing wrong?


Thanks!
0
codefingerAuthor Commented:
sorry, typo,  should have said...

.....and found I was always getting an NaN value in inchside4 when this was called

 parseInt(inchside3)    --   The value of inchside3 at this point is .5".
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

David S.Commented:
The code is not equivalent. The minimized code has an error. If trim() actually removes any character it will change the length of the string that substring() is operating on without affecting the length being used to determine how long the resulting string should be.

What's stranger is that it doesn't seem to make sense to use a numerical string as the basis for how to truncate it.

Also it's best to pass the second argument to parseInt() so any leading zeroes don't result in the string getting parsed in octal instead of decimal.

I think this is what Steve intended:
$y[1] = $y[1].trim();
$in = parseInt($y[1].substring($y[1].length-1), 10) || '0';

Open in new window

0
Steve BinkCommented:
The problems I ran into with that data point:
  - it was prefixed with a space character
  - parseInt() returns NaN on '.4'

My strategy for fix was to trim the initial string, then return '0' if parseInt() failed.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
codefingerAuthor Commented:
parseInt()  on the right side of the split was a bit of a red herring, but that was my own fault.  I should have mentioned I needed to convert the formats to total inches.

Splitting on the apostrophe was still key, though.   Then I just had to use the substring function to remove the quotes from the right side and use the Number function to add left and right sides back together for total inches.   Just a variation of what Steve said in the first place.

Steve would have received all the points, but I think Kravmir 's points were valid, and helped me stop trying to make Steve's code work as it was and rethink the problem.

Tempted to give a B instead of an A because neither expert mentioned whether or not a regular expression would have been helpful here.
But that is a little nitpicky, and together they both did help me solve the problem. so an A it is.

I am assuming once I click submit, I can allocate the points as I see fit and they won't automatically be split 50/50.  

Let me apolgize in advance if that is not the case.
0
Steve BinkCommented:
RE: Using regex, I think that would have been more complicated.  Because you're dropping the decimal portions, you would end up with a conditional replacement for something like 5' .4".  You would have to replace just those instances with "0", where all the others are being replaced with "whatever comes before the decimal".  At the least, you would have needed a series of two replacements - one for the "normal" fit, and a second for the edge case.
0
David S.Commented:
In the replace() method for strings in JS you can use a function as the replacement instead of a string which would allow this to be done using a single regular expression, however, in this case it's more efficient to just split the string in the first place.

Instead of using parseInt() it might actually be better to use parseFloat() and then Math.floor() or Math.round().
function pretty($x) {
  var $y = $x.split(/'\s*/),
      $ft = parseInt($y[0],10),
      $in = Math.floor(parseFloat($y[1]));
  return $ft + "'" + $in + '"';
}

Open in new window

P.S. Please don't give a lower grade when you can post a reply asking for further clarification on some point. Thank you for not downgrading our responses this time.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.