JS - Power sign / exponent to number

Viewed 664

Is there an easier way of converting power sign / exponent symbols to their number equivalent (ie from to 8) than just a bunch of replaces?

EDIT: Thank you all for the solutions!

4 Answers

You could create a regular expression and perform one call of replace, giving it a callback function:

let sup = {
  "⁰": "0",
  "¹": "1",
  "²": "2",
  "³": "3",
  "⁴": "4",
  "⁵": "5",
  "⁶": "6",
  "⁷": "7",
  "⁸": "8",
  "⁹": "9",
  "⁺": "+",
  "⁻": "-",
  "⁼": "=",
  "⁽": "(",
  "⁾": ")",
  "ⁿ": "n",
  "ⁱ": "i"
};

let regex = RegExp(`[${Object.keys(sup).join("")}]`, "g");

// demo
let s = "x⁽ⁱ⁻²⁾ * y³";
let norm = s.replace(regex, c => sup[c]);
console.log(s);
console.log(norm);

Create an object containing the mappings you need and then loop over that. Example:

const map = {"⁰": "0","¹": "1","²": "2","³": "3","⁴": "4","⁵": "5","⁶": "6","⁷": "7","⁸": "8","⁹": "9"};
let string = "drtyhnmk¹¹²";
for (const i of Object.keys(map)) {
  string = string.replace(new RegExp(i, 'g'), map[i]);
}
console.log(string);

A regex is needed to get global replace.

I'm afraid, it's only possible by manual replacement. I wouldn't recommend the usage of Regexp, it's quite slow on long texts, especially in the loop.

function decode_superscript(text) {
    var map = {
        "⁰":"0","¹":"1", "²":"2",  "³":"3", "⁴":"4","⁵":"5","⁶":"6","⁷":"7","⁸":"8","⁹":"9","ᵃ":"a","ᵇ":"b","ᶜ":"c","ᵈ":"d","ᵉ":"e","ᶠ":"f","ᵍ":"g","ʰ":"h","ᶦ":"i","ʲ":"j","ᵏ":"k","ˡ":"l","ᵐ":"m","ⁿ":"n","ᵒ":"o","ᵖ":"p","ᑫ":"q","ʳ":"r","ˢ":"s","ᵗ":"t","ᵘ":"u","ᵛ":"v","ʷ":"w","ˣ":"x","ʸ":"y","ᶻ":"z","ᴬ":"A","ᴮ":"B","ᶜ":"C","ᴰ":"D","ᴱ":"E","ᶠ":"F","ᴳ":"G","ᴴ":"H","ᴵ":"I","ᴶ":"J","ᴷ":"K","ᴸ":"L","ᴹ":"M","ᴺ":"N","ᴼ":"O","ᴾ":"P","Q":"Q","ᴿ":"R","ˢ":"S","ᵀ":"T","ᵁ":"U","ⱽ":"V","ᵂ":"W","ˣ":"X","ʸ":"Y","ᶻ":"Z","⁺":"+","⁻":"-","⁼":"=","⁽":"(","⁾":")"};
    var charArray = text.split("");
    for(var i = 0; i < charArray.length; i++) {
        if( map[charArray[i].toLowerCase()] ) {
            charArray[i] = map[charArray[i]];
        }
    }
    text = charArray.join("");
    return text;
}

console.log(decode_superscript("⁰¹²"))

This can be done by taking advantage of superscript digits' code points:

function superscriptToASCIIDigits(str) {
  let out = "";
  for (let i=0; i<str.length; i++) { // `for ... of` is not necessary because superscript digits don't form surrogate pairs.
    const charCode = str.charCodeAt(0);
    if (charCode === 0x2070 || charCode >= 0x2074 && charCode <= 0x2079) { // All digits except 1 and 2
      out += String.fromCharCode(charCode - 0x2040);
    } else if (charCode === 0xB2 || charCode === 0xB3) { // 1 and 2
      out += String.fromCharCode(charCode - 0x80);
    } else { // All other characters
      out += str[i];
    }
  }
  return out;
}

No replacement map needed.

Related