Home > Net >  How to add a keyword before string using regex in JS?
How to add a keyword before string using regex in JS?

Time:12-06

I am making an application where I have a string from which I will form an array with the help of regex.

Eg..,

String: DEVICE_SIZE IN ('036','048', '060','070')

Output:

{
    "DEVICE_SIZE": [
      "036",
      "048",
      "060",
      "070"
    ]
}

Like this for all string, we follow the following code to get the array data.

Here if there is a NOT keyword before the key, then we add NOT *key* like "NOT DEVICE_DISCHARGE_AIR"

Requirement:

I have a string like NOT (DEVICE_SERIES IN ('LV') AND DEVICE_VOLTAGE IN ('A','8') AND DEVICE_SIZE IN ('007','009','012','018')).

So here after NOT there is a parenthesis, so after NOT if there is a parenthesis then I need to add the key as

"NOT DEVICE_SERIES":["LV"],

"NOT DEVICE_VOLTAGE":["A", "8"] ,

"NOT DEVICE_SIZE": ['007','009','012','018']

Current scenario:

But right now, it is not adding the NOT keyword before of key.

Working Example:

const stringOne = "DEVICE_SIZE IN ('036','048', '060','070') AND DEVICE_VOLTAGE IN ('1','3') AND NOT DEVICE_DISCHARGE_AIR IN ('S') AND NOT DEVICE_REFRIGERANT_CIRCUIT IN ('H', 'C')";

const stringTwo = "DEVICE_SERIES IN ('LV') AND DEVICE_ELECTRICAL IN ('K') AND NOT (DEVICE_SERIES IN ('LV') AND DEVICE_VOLTAGE IN ('A','8') AND DEVICE_SIZE IN ('007','009','012','018'))";


const regex = /((?:\bNOT\s )?\w )\s IN\s \('([^()]*)'\)/g;

const getTransformedData = (string) => {
   return Array.from(
  string.matchAll(regex), m =>
  ({
    [m[1]]: m[2].split(/',\s*'/)
  })
 )
}


console.log(getTransformedData(stringOne)); // Working fine

console.log(getTransformedData(stringTwo)); // Need to include NOT infront of each key as it is union

How can I add NOT keyword in front of each key if it comes with the pattern of NOT and then the parenthesis like in stringTwo?

Expected result:

"NOT DEVICE_SERIES":["LV"],

"NOT DEVICE_VOLTAGE":["A", "8"] ,

"NOT DEVICE_SIZE": ['007','009','012','018']

CodePudding user response:

You may use this Javascript solution for your problem:

const stringOne = "DEVICE_SIZE IN ('036','048', '060','070') AND DEVICE_VOLTAGE IN ('1','3') AND NOT DEVICE_DISCHARGE_AIR IN ('S') AND NOT DEVICE_REFRIGERANT_CIRCUIT IN ('H', 'C')";
const stringTwo = "DEVICE_SERIES IN ('ALV', 'FOO') AND DEVICE_ELECTRICAL IN ('K') AND NOT (DEVICE_SERIES IN ('LV') AND DEVICE_VOLTAGE IN ('A','8') AND DEVICE_SIZE IN ('007','009','012','018'))";

const pat1 = String.raw`(\bNOT)\s \(((?:[\w\s] \([^)] \)) )\)`;
const pat2 = String.raw`(\w )\s IN\s \('([^()]*)'\)`;
const re1 = new RegExp(pat1   '|'   pat2, "g");
const re2 = new RegExp(pat2, "g");
const re3 = /',\s*'/;

const getTransformedData = (string) => {
  var res = [];
  const matches = string.matchAll(re1);
  for (const match of matches) {
    if (match[1] == "NOT") {    
      res.push(...Array.from(
      match[2].matchAll(re2), m =>
      ({
        [match[1]   ' '   m[1]]: m[2].split(re3)
      })));
    } else {
      res.push(
      ({
        [match[3]]: match[4].split(re3)
      }));
    }
  }
  return res;
}

console.log(getTransformedData(stringOne));
console.log(getTransformedData(stringTwo));

  • Regex string pat2 is same as what you already have
  • Regex string pat1 matches a string that has NOT (...) substring.
  • We combine pat1 and pat2 to build a regex re1 which is applied first against input string. This regex matches NOT (...) pattern or word in (...) sub-patterns.
  • We capture NOT in capture group #1 and text inside (...) in capture group #2.
  • When match[1] == "NOT" we apply re2 again on the match[2] to get our desired matches
  • Regex re3 is your split regex
  • Related