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

2
  • What does not work? What error do you get? Commented Dec 27, 2022 at 8:41
  • Any reason it has to be regex, rather than simple string manipulation? Commented Dec 27, 2022 at 8:43

3 Answers 3

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);

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

2 Comments

Hi there, all is well? Do you agree with the duplicate here?
@Thefourthbird As a matter of fact, no, I don't. That duplicate doesn't really cover this question.
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);

Comments

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);

6 Comments

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 Hey man, yes of course. The Object.fromEntries() transforms a list of key-value pairs into an object The Array.from() creates a new, shallow-copied Array instance from an iterable or array-like object.
The String.prototype.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.
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 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)
|

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.