I have the following string:
person:juan&age:24&knowledge:html
The problem is that sometimes the string is:
knowledge:html&person:juan&age:24
And it can change the position of the keys and the values.
In this case I would write something like this:
const keys = ["person", "age", "knowledge"];
const keyAndValues = "person:juan&age:24&knowledge:html";
const result = [];
keys.forEach(key => {
const indexKeyValues = keyAndValues.indexOf(key);
if (indexKeyValues !== -1) {
const lastCharIndex = keyAndValues.substring(indexKeyValues).indexOf("&");
return keyAndValues.substring(indexKeyValues + key.length, lastCharIndex === -1 ? keyAndValues.substring(indexKeyValues).length - 1 || lastCharIndex);
}
});
But I don't like it and it would be great if I could do something like:
const resultsExpected = /regexGroupedRegardlessOfPosition/g.match("person:juan&age:24&knowledge:html");
console.log(resultsExpected); // { person: "juan", age: 24, knowledge: "html" }
答案 0 :(得分:3)
You could split the string and then the parts and take the key/values for an object.
function getValues(string) {
var object = {};
string && string.split('&').forEach(p => {
var [key, ...value] = p.split(':');
object[key] = value.join(':');
});
return object;
}
console.log(getValues("knowledge:html&person:juan&age:24"));
console.log(getValues("foo:bar:baz&cool:space:aliens:survive"));
console.log(getValues(""));
答案 1 :(得分:3)
Here is a single expression to get the object:
const keyAndValues = "person:juan&age:24&knowledge:html";
const obj = Object.assign(...keyAndValues.split('&').map(s => s.split(':'))
.map(([k, v]) => ({ [k]: v }))
);
console.log(obj);
This uses ES6 destructuring assignment, spread syntax and computed property names.
答案 2 :(得分:2)
(knowledge|person|age):([^&]+)
You probably don't want to, but to accept any key:
(\w+):([^&]+)
答案 3 :(得分:1)
As Phiter said, I don't think regex really helps you here. You probably know the old joke: "I have a problem. I know! I'll use regex! Oh, now I have two problems."
I'd split the string on &
, and then for each substring, on :
, and fill in the values from that:
function strToObject(str) {
var rv = {};
str.split("&").forEach(function(substr) {
var index = substr.indexOf(":");
if (index === -1) {
rv[substr] = undefined;
} else {
rv[substr.substring(0, index)] = substr.substring(index+1);
}
});
return rv;
}
Live Example:
function strToObject(str) {
var rv = {};
str.split("&").forEach(function(substr) {
var index = substr.indexOf(":");
if (index === -1) {
rv[substr] = undefined;
} else {
rv[substr.substring(0, index)] = substr.substring(index+1);
}
});
return rv;
}
console.log(strToObject("person:juan&age:24&knowledge:html"));
console.log(strToObject("knowledge:html&person:juan&age:24"));
.as-console-wrapper {
max-height: 100% !important;
}
This could be made terser, by:
:
characters. I've used indexOf
rather than the simpler split
to separate name and value to allow for the possibility that the value will contain a :
(e.g., foo:blah:blah&bar:blah
where foo
is "blah:blah"
) — many if not most other solutions here throw away part of the value in that case答案 4 :(得分:1)
I think a simple function that would convert this type of string to an object can be a better solution. Look at this:
var keyAndValues = "person:juan&age:24&knowledge:html";
function weirdStringToObject(str){
var obj = {};
str.split('&').forEach(function(substr){
var kv = substr.split(':');
var key = kv[0];
var value = kv[1] || null;
obj[key] = value;
});
return obj;
}
console.log(weirdStringToObject(keyAndValues));
It requires a little bit of extra validation, but it's easy to follow from here.
答案 5 :(得分:1)
You can make use of:
Array.prototype.reduce()
String.prototype.split()
String.prototype.slice()
String.prototype.indexOf()
Working Example:
const str = "person:juan&age:24&knowledge:html";
let result = str.split("&").reduce((r, s) => {
let i = s.indexOf(':');
r[s.slice(0, i)] = s.slice(i + 1);
return r;
}, {});
console.log(result);