1

I exported a large excel spreadsheet as html and I want to calculate some cells' values in JavaScript. I smuggled the expressions used in excel as data-xxx info in every P I intend to fill.

Is there a way of translating the data-xxx to JavaScript code so that it'll give me the wanted value?

Example strings:

06A02
min(06C02;06C03)
max(03B04;03B05;03B06)
max(min(07A01;07A02;08F01);min(09A01;09A02))
max(min(03B01;03B02;03B03);08C02;09B01;09C02)
max(min(07A03;07A04;08F02);min(09A03;09A04);09C02)
max(09B05;min(07A01;07A02;08F01);min(09A01;09A02))
max(09B05;min(07A03;07A04;08F02);min(09A03;09A04);09B01;09C02)

06A02 and similar are just keys of values stored in localStorage, saved via another page's form.

I thought I could just use ifs and elses and slice the string piece by piece, but that would make a giant tree I could make too many mistakes in.

I thought of regular expressions to shorten the tree, but I'm not sure if it's that much better.

There may be a way I don't know yet.

Example HTML:

<TR>
<TD>Prolonged lack of access...</TD>
<TD>A</TD>
<TD>A</TD>
<TD><p id="ar1_11e" data-eks="AC.E.Inc"></p></TD>
<TD>1</TD>
<TD><p id="ar1_11za" data-zap="03D01"></p></TD>
<TD><p id="ar1_11i" data-imp="ar1"></p></TD>
<TD><p id="ar1_11og" data-ogr="min(03D02;03D03)"></p></TD>
<TD><p id="ar1_11la" data-lag="04A05"></p></TD>
<TD><p id="Par1_11"></p></TD>
<TD><p id="War1_11"></p></TD>
<TD><p id="Rar1_11"></p></TD>
<TD><p id="Oar1_11"></p></TD>
</TR>

2 Answers 2

3

@hev1 has provided an excellent solution. If you wanted to use regex you could do something like this:

function evalExcel(rawString) {
  // match expected format, prevent easy eval injection
  const safeMatch = /^(min|max|[();]|[A-F0-9]{5})*$/;

  if (rawString.match(safeMatch) && window.localStorage) {
    const regexNum = /[A-F0-9]{5}/g;
    const jsCode = rawString.replace(/;/g, ", ")
      .replace(/min/g, "Math.min")
      .replace(/max/g, "Math.max")
      .replace(regexNum, "+localStorage.getItem(\"$&\")");
    return eval(jsCode);
  }
  return null;
}

Demo

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

4 Comments

I like this one. I'd change safeMatch to /^(min|max|[A-F0-9]{5})/ though, because single value is a valid expression as well (see OP's example & HTML).
I’m not sure what you mean, safeMatch already matches a single value.
Ah, figured the issue - the ; is missing in the linked demo regexp (the [()] part), but I thought it was not working because of $.
This is great. Somehow all I get in my Ps are zeroes, but I believe it's a defect in the rest of the code somewhere. Thanks a lot, that's exactly what I needed!
1

You can use a simple recursive inner function.

function getValue(str){
    let idx = 0;
  function helper(){
    let op = Math[str.slice(idx,idx+3)];
    let opened = 1, closed = 0;
    let args = [];
    for(idx += 3; idx < str.length && opened != closed; idx++){
        if(str.indexOf("min", idx) == 0 || str.indexOf("max", idx) == 0){
        args.push(helper());
      } else {
        let delimIdx = str.indexOf(";", idx);
        if(delimIdx != -1){
            args.push(+localStorage.getItem(str.slice(idx, delimIdx)));
        } else {
            args.push(+localStorage.getItem(str.slice(idx,str.indexOf(')', idx))));
        }
      }
    }
    return op(...args);
  }
  return str.startsWith("min") || str.startsWith("max") ? helper(): +localStorage.getItem(str);
}

Demo

9 Comments

I'm trying out this function and it seems to have a mistake in "return op(...args);" Console says op is not a function and I don't understand it either. Why is helper() being pushed to args, why is it on the return?
The demo does nothing when I try to run it and the code pasted in my .js file raises an error in he line I mentioned above.
@Warxuaroz Does the demo itself work? Could you provide a reproducible example of it not working?
@Warxuaroz Could you put your code in a JSFiddle for me?
@Warxuaroz I've fixed it. Try it out.
|

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.