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 hasNOT (...)
substring. - We combine
pat1
andpat2
to build a regexre1
which is applied first against input string. This regex matchesNOT (...)
pattern orword in (...)
sub-patterns. - We capture
NOT
in capture group #1 and text inside(...)
in capture group #2. - When
match[1] == "NOT"
we applyre2
again on thematch[2]
to get our desired matches - Regex
re3
is your split regex