2

I have this string

java=10514;js=237;jsp=3995;web=5;xml=42

and I'd like to extract, in separate variables, the value numbers for each language, using javascript and a regular expression that is, for the "java" case, the follow

(?<=java=).*?(?=;|$)

I've tried this code

var myString = "java=10514;js=237;jsp=3995;web=5;xml=42";
var regexp_java = new RegExp('(?<=java=).*?(?=;|$)', 'g');    
var ncloc_java = sonar_myString.match(regexp_java);
var regexp_js = new RegExp('(?<=js=).*?(?=;|$)', 'g');    
var ncloc_js = sonar_myString.match(regexp_js);
var regexp_jsp = new RegExp('(?<=jsp=).*?(?=;|$)', 'g');    
var ncloc_jsp = sonar_myString.match(regexp_jsp);
var regexp_web = new RegExp('(?<=web=).*?(?=;|$)', 'g');    
var ncloc_web = sonar_myString.match(regexp_web);
var regexp_jsp = new RegExp('(?<=jsp=).*?(?=;|$)', 'g');    
var ncloc_jsp = sonar_myString.match(regexp_jsp);

but it doesn't work.

Any suggestion will be appreciated and thank you in advance

Ryszard Czech
  • 18,032
  • 4
  • 24
  • 37
Cesare
  • 1,629
  • 9
  • 30
  • 72

3 Answers3

3

I believe that you are using the wrong data structure here. Rather than trying to use individual variables for each language, you can instead use a hashmap. First split to the string on semicolon, and then stream that to get each language and value.

var input = "java=10514;js=237;jsp=3995;web=5;xml=42";
var map = {};
input.split(";").forEach(x => map[x.split("=")[0]] = x.split("=")[1]);
console.log(map);
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
2

Does it really need to be done with Regex? Anyways I'm providing you with 2 solutions.

const string = "java=10514;js=237;jsp=3995;web=5;xml=42";

let result1 = string.split(';').reduce((acc, curr) => {
  let [key, value] = curr.split('=');
  acc[key] = value;
  return acc;
}, {});

console.log(result1);

let result2 = {};
let regex = /([a-z]+)\s*=\s*(\d+)/g;
let check;

while (check= regex.exec(string)) {
  result2[check[1]] = check[2];
}

console.log(result2);
Juljo Shahini
  • 138
  • 10
2

You don't have to create separate patterns and variables, Instead you can use 2 capture groups and then create an object with keys and values (assuming there are no duplicate keys)

\b(java|jsp?|web|xml)=([^;\s]+)

Explanation

  • \b A word boundary
  • (java|jsp?|web|xml) Match one of the alternatives
  • = Match literally
  • ([^;\s]+) Capture group 2, match 1+ chars other than a whitespace char or ;

See a regex demo.

const myString = "java=10514;js=237;jsp=3995;web=5;xml=42";
const regex = /\b(java|jsp?|web|xml)=([^;\s]+)/g;
const kv = Object.fromEntries(
  Array.from(
    myString.matchAll(regex), m => [m[1], m[2]]
  )
)
console.log(kv)
console.log(kv.java);
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • Hey buddy, nice code. Could you please explain it from `Object.fromEntries` to its completion. Trying to learn JS but not able to fully understand it. I get that you are doing it in 2 capturing groups and putting output into key value pair format but how its working inside JS thing not sure. Will be grateful to you, Thank you. – RavinderSingh13 Jan 02 '23 at 06:19
  • 1
    @RavinderSingh13 Hey man, yes of course. The [Object.fromEntries()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) `transforms a list of key-value pairs into an object` The [Array.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) `creates a new, shallow-copied Array instance from an iterable or array-like object.` – The fourth bird Jan 02 '23 at 13:04
  • 1
    The [String.prototype.matchAll()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll) `method returns an iterator of all results matching a string against a regular expression, including capturing groups.` So `matchall` returns the iterator with the 2 capture group values to `Array.from`, which returns an array of arrays which looks like `[["java","10514"],["js","237"]]` That is a datastructure that Object.fromEntries can process to create an object with key-value pairs. – The fourth bird Jan 02 '23 at 13:05
  • 1
    Thank you buddy, let me process these comments, thank you for detailed explanation, let us keep these for future users if you ok with it, cheers ++ – RavinderSingh13 Jan 02 '23 at 13:13
  • Hey, one more question could you please do explain more on `m => [m[1], m[2]]` code? I am not that expert in JS so need to completely understand it, thank you buddy for your help cheers. – RavinderSingh13 Jan 02 '23 at 13:44
  • 1
    @RavinderSingh13 This whole part `m => [m[1], m[2]]` is a function that is passed as the second parameter to `Array.from()` as the inline mapping function. The outer square brackets here `[...]` create an array that will hold the 2 values, where `m[1]`is the capture group 1 value, and `m[2]` the capture group 2 value. So we are basically mapping each item of result from matchAll to an array of array's (where each inner array has 2 values) – The fourth bird Jan 02 '23 at 14:04