TransWikia.com

Javascript Regex, Add space before and after math operators if there is none

Stack Overflow Asked by Mister SirCode on January 10, 2021

Im trying to make the perfect math parser for my discord bot.

Currently I have a simple function parser that takes in a string which has a ton of .replace methods to clear up a bunch of junk or formatting things leftover from discord, or just replaces {} with () and such quality of life things…

var parseArgs = args.toLowerCase().replace(/ -o/g, "").replace(/x/g, "*").replace(/[a-z]/g, "")
    .replace(/{/g, "(").replace(/}/g, ")").replace(/[/g, "(").replace(/]/g, ")").replace(/+=/g, "+")
    .replace(/-=/g, "-").replace(/'/g, "").replace(/`/g, "").replace(/"/g, "");

var origArgs = args.toLowerCase().replace(/`/g, "").replace(/ -o/g, "");

const output = parseMath(parseArgs);

This is nice and all, but If you input an equation like this:
!math 1 + 1aaa+aaaa2{55>>2}

The parser will output:
1 + 1+2*(55>>2)

I want it to output:
1 + 1 + 2 * (55 >> 2)

Which easily gets parsed by my function, but the equation is sent into the chat, and its quite ugly.

Im asking if theres a simple regex formula to check if a math operator (+ - / * x ( ) >> ^ += -= == ===) like those is between any numbers

so 1+2/3(4>>2) and 3>>4===3*4 will turn into 1 + 2 / 3 (4 >> 2) and 3 >> 4 === 3 * 4 respectively.

Edit: I see how crappy my replaces are, so I simplified them:

var parseArgs = args.toLowerCase().replace(/x/g, "*").replace(/ -o|[a-z]|"|'|`/g, "")
    .replace(/{|[/g, "(").replace(/}|]/g, ")").replace(/+=/g, "+").replace(/-=/g, "-");
var origArgs = args.toLowerCase().replace(/ -o|`/g, "");

One Answer

First remove anything that isn't mathematical (remove anything that isn't a number or a possible operator), then use .replace to match zero or more spaces, followed by any of the operators, then match zero or more spaces again, and replace with the operator with one space on each side:

const parse = (args) => {
  const argsWithOnlyMath = args.replace(/[^d+-/*x()>^=]/g, ' ');
  const spacedArgs = argsWithOnlyMath
    .replace(/s*(D+)s*/g, ' $1 ') // add spaces
    .replace(/ +/g, ' ') // ensure no duplicate spaces
    .replace(/( /g, '(') // remove space after (
    .replace(/ )/g, ')'); // remove space before )
  console.log(spacedArgs);
};
parse('!math 1 + 1aaa+aaaa2(55>>2)');
parse(' 1+2/3(4>>2) ');
parse('3>>4===3*4');

To also add spaces before ( and after ), just add more .replaces:

const parse = (args) => {
  const argsWithOnlyMath = args.replace(/[^d+-/*x()>^=]/g, ' ');
  const spacedArgs = argsWithOnlyMath
    .replace(/s*(D+)s*/g, ' $1 ') // add spaces
    .replace(/(/g, ' (') // add space before (
    .replace(/)/g, ') ') // add space after )
    .replace(/ +/g, ' ') // ensure no duplicate spaces
    .replace(/( /g, '(') // remove space after (
    .replace(/ )/g, ')'); // remove space before )
  console.log(spacedArgs);
};
parse('!math 1 + 1aaa+aaaa2(55>>2)');
parse(' 1+2/3(4>>2) *()');
parse('3*()');

Correct answer by CertainPerformance on January 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP