简体   繁体   中英

Find all imperial units and replace with their metric counterparts

I'm looking for a way to go through a whole website looking for imperial units, eg lbs, feet, inches and convert them to metrical values, kilos, meters, centimeters.

Example:

<main>
  <h1>Top speed of new car is 300mph/h</h1>
  <p>
    Such a fast car, previously going only 250 mph, now topping speeds up to 300mph.
    And it only weighs 300lbs, 20 pounds less than before!
  </p>
</main>

Becomes:

<main>
  <h1>Top speed of new car is 482.8km/h</h1>
  <p>
    Such a fast car, previously going only 402km/h, now topping speeds up to 482.8km/h.
    And it only weighs 136kg, 9kg less than before!
  </p>
</main>

The question isn't how to convert from mph/lbs to kmh/kg, but how to find and store values such as "10mph", "10 mph", "200lbs", "200 lbs", "200 pounds" in a good way, convert them and finally replacing them.

Any pointers would be very helpful!

Edit A simplified example of what I want to achieve:

<p>This is 10 lbs</p>
<p>This is 20lbs</p>

<script>
  $('p').each(function(){
    var text = $(this).text().toLowerCase();

    if(text.indexOf('lbs') >= 0) {
      // Store "XX lbs" in a variable
      // Wrap the above created variable in a <span>
      // Convert the variable to kg
      // Replace the text in <span> with the value in kilogram
      // Output: <p>This is <span>4.5kg</span></p>
    }

  });
</script>

Well you can start by building a mapping of units that should be converted from what to what and their conversion ratios:

var unitMapping = {
  mph : { unit : 'km/h', ratio : 1.609 }, // there is no such thing as mph/h ?  
  lbs : { unit : 'kg', ratio : 0.45 },
  pounds : { unit : 'kg', ratio : 0.45 }
};

Now you need to replace the text with the correct values. First create a regexp that matches all your units:

var regexp = new RegExp('(\\d*) ?(' + Object.keys(unitMapping).join('|') + ')', 'g');

Write a clever replace function that takes a non-standard unit and returns a standard one:

var replaceFunction = function(match, value, unit){
  return value*unitMapping[unit].ratio + unitMapping[unit].unit;
};

And finally bring it all together by taking the text and replacing it with the correct version:

var replaceNode = document.querySelector('main');
replaceNode.innerHTML = replaceNode.innerHTML.replace(regexp, replaceFunction);

DEMO: http://jsbin.com/UPEmEjuS/1/edit

As you can see, there is some repetition in unitMapping. The solution can obviously be improved by making the mapping depend on the normalized units, but i chose this option because it makes the code clearer for a SO post.

Shameless plug: webpage-unit-conversion :

JavaScript code that can be embedded in a page to convert units in the page between metric (SI) units and British Imperial/US units along with CSS that allows flexible choosing of which units are displayed.

There's a demo page that shows how it works. It's got some biases, eg "degree" is assumed to refer to temperature instead of angle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM