faster way to extract key value from string using pure JavaScript - javascript

I have string that contains key value separated by diff. kind of chars.
I need to use pure JavaScript ( no lib like jquery or ecma 5 or 6) regx or logic that is faster to extract key value and create javasciprt object.
string can be like as following and it will be not so long .mostly i can have 2 or 3 key value pairs.
"key!value~key!value"
"c!XXXXXXX~e!YYYYY~k!YYXXXX~d!" where "~" separate between key value and "!"
separates between key and value.
Out put after parsting string will be
{c:"XXXXXXX",e:"YYYYY",k:"YYXXXX",d:''}
Is Regx is faster and what can be pattern?
or normal forloop and split function will be faster?

You don't need to use regex to separate the key-value pairs just use split function of string object. use code :
const KV_SEP = "!";
const ENTITY_SEP = "~";
"c!XXXXXXX~e!YYYYY~k!YYXXXX~d!".split(ENTITY_SEP).map(function(val){
return [val.split(KV_SEP)];
});

This is regex version
function splitString(str) {
const KEY_INDEX = 1
const VALUE_INDEX = 2
const myKeyValue = {}
const myRegex = /(?:([a-z])!([a-zA-z]*)~?)/g
while(1) {
match = myRegex.exec(str)
if (match === null) break
myKeyValue[match[KEY_INDEX]] = match[VALUE_INDEX]
}
return myKeyValue
}
console.log('result:', splitString('c!XXXXXXX~e!YYYYY~k!YYXXXX'))

Related

Extract part of a string which start with a certain word in Javascript

I have the following string
"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,
I need to get string after "ssu":" the Result should be 89c4eef0-3a0d-47ae-a97f-42adafa7cf8f. How do I do it in Javascript but very simple? I am thinking to collect 36 character after "ssu":".
You could build a valid JSON string and parse it and get the wanted property ssu.
var string = '"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,',
object = JSON.parse(`{${string.slice(0, -1)}}`), // slice for removing the last comma
ssu = object.ssu;
console.log(ssu);
One solution would be to use the following regular expression:
/\"ssu\":\"([\w-]+)\"/
This pattern basically means:
\"ssu\":\" , start searching from the first instance of "ssu":"
([\w-]+) , collect a "group" of one or more alphanumeric characters \w and hypens -
\", look for a " at the end of the group
Using a group allows you to extract a portion of the matched pattern via the String#match method that is of interest to you which in your case is the guid that corresponds to ([\w-]+)
A working example of this would be:
const str = `"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,`
const value = str.match(/\"ssu\":\"([\w-]+)\"/)[1]
console.log(value);
Update: Extract multiple groupings that occour in string
To extract values for multiple occurances of the "ssu" key in your input string, you could use the String#matchAll() method to achieve that as shown:
const str = `"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,"ssu":"value-of-second-ssu","ssu":"value-of-third-ssu"`;
const values =
/* Obtain array of matches for pattern */
[...str.matchAll(/\"ssu\":\"([\w-]+)\"/g)]
/* Extract only the value from pattern group */
.map(([,value]) => value);
console.log(values);
Note that for this to work as expected, the /g flag must be added to the end of the original pattern. Hope that helps!
Use this regExp: /(?!"ssu":")(\w+-)+\w+/
const str = '"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,';
const re = /(?!"ssu":")(\w+-)+\w+/;
const res = str.match(re)[0];
console.log(res);
You can use regular expressions.
var str = '"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049,'
var minhaRE = new RegExp("[a-z|0-9]*-[a-z|0-9|-]*");
minhaRE.exec(str)
OutPut: Array [ "89c4eef0-3a0d-47ae-a97f-42adafa7cf8f" ]
Looks almost like a JSON string.
So with a small change it can be parsed to an object.
var str = '"sis":4,"sct":15,"ssu":"89c4eef0-3a0d-47ae-a97f-42adafa7cf8f","ssv":384,"siw":96554,"scx":1049, ';
var obj = JSON.parse('{'+str.replace(/[, ]+$/,'')+'}');
console.log(obj.ssu)

JavaScript Split with RegEx without Global Match

I have an expression.
var expression = "Q101='You will have an answer here like a string for instance.'"
I have a regular expression that searches the expression.
var regEx = new regExp(/=|<>|like/)
I want to split the expression using the regular expression.
var result = expression.split(regExp)
This will return the following:
["Q101", "'You will have an answer here ", " a string for instance'"]
This is not what I want.
I should have:
["Q101", "'You will have an answer here like a string for instance'"]
How do I use the regular expression above to split only on the first match?
Since you only want to grab the two parts either side of the first delimiter it might be easier to use String.match and discard the whole match:
var expression = "Q101='You will have an answer here like a string for instance.'";
var parts = expression.match(/^(.*?)(?:=|<>|like)(.*)$/);
parts.shift();
console.log(parts);
expression = "Q101like'This answer uses like twice'";
parts = expression.match(/^(.*?)(?:=|<>|like)(.*)$/);
parts.shift();
console.log(parts);
JavaScript's split method won't quite do what you want, because it will either split on all matches, or stop after N matches. You need an extra step to find the first match, then split once by the first match using a custom function:
function splitMatch(string, match) {
var splitString = match[0];
var result = [
expression.slice(0, match.index),
expression.slice(match.index + splitString.length)
];
return result;
}
var expression = "Q101='You will have an answer here like a string for instance.'"
var regEx = new RegExp(/=|<>|like/)
var match = regEx.exec(expression)
if (match) {
var result = splitMatch(expression, match);
console.log(result);
}
While JavaScript's split method does have an optional limit parameter, it simply discards the parts of the result that make it too long (unlike, e.g. Python's split). To do this in JS, you'll need to split it manually, considering the length of the match —
const exp = "Q101='You will have an answer here like a string for instance.'"
const splitRxp = /=|<>|like/
const splitPos = exp.search(splitRxp)
const splitStr = exp.match(splitRxp)[0]
const result = splitPos != -1 ? (
[
exp.substring(0, splitPos),
exp.substring(splitPos + splitStr.length),
]
) : (
null
);
console.log(result)

Raw String to normal string javascript

Normal String assignment:
var str1 = "\320";
console.log(str1); // "Ð"
Raw String assignment:
var str2 = String.raw`\320`;
console.log(str2); // "\320"
In raw string, the backslashes are not interpreted. I need to interpret them so that "\320" will become "Ð". Should I have to convert the raw string to normal String. If so, How? If not so, what else should I do and how do I do?
The thing is, this code is octal, and since these are mapped with linguistic symbols, javascript interpretes it when defining new string.
what you can do is make a map of all the symbols you require with their key as actual string and value as actual symbol.
for ex -
var map = {
"\\320": "\320"
}
console.log(map);
now you can search you text in the map and get the required value.
var str2 = String.raw`\320`;
var s = map[str2];
console.log(s);
to make the map, try this -
visit this site - https://brajeshwar.github.io/entities/
and run this code on console
// for latin
var tbody = document.getElementById("latin");
var trs = tbody.children;
var map = {};
for(i=1;i<trs.length;i++) {
console.log(trs[i].children[6].innerText);
key = trs[i].children[6].innerText;
value = trs[i].children[1].innerText;
map[key] = value;
}
now console map, stringify it, and paste the string in your code and parse it.
I have done this only for latin, similarly do this for other elements also.
Question is a couple of months old, but I think this answer is your best bet, yet. Transforming escape sequences from raw strings is very much doable with ES6 String.fromcodepoint(<hex-value>). I'm in the middle of writing an NPM package which deals with this exact scenario.
First, you need a regular expression which matches all escape sequences in your string. I've used this as a reference for all the different ones. (I use a raw string for this to avoid spamming backslashes)
let [single, ...hex] = String.raw`
\\[bfnrtv0'"\\]
\\x[a-fA-F0-9]{2}
(\\u[a-fA-F0-9]{4}){1,}
\\u\{([0-9a-fA-F]{1,})\}`
.split("\n").slice(1).map(cur => cur.trim());
let escapes = new RegExp(`(${[single].concat(hex).join("|")})`, "gm"),
// We need these for later when differentiating how we convert the different escapes.
uniES6 = new RegExp(`${hex.pop()}`);
single = new RegExp(`${single}`);
Now you can match all the escapes; reserved single characters, extended ASCII range, ES6 "Astral" unicode hexadecimals and surrogate pairs. (except octals because they're deprecated, but you can always add it back). The next step is writing a function which can replace the code points with the corresponding symbols. First a switch-like function for singles:
const singleEscape = seq =>
(() => ({
"\\b" : "\b",
"\\f" : "\f",
"\\n" : "\n",
"\\r" : "\r",
"\\t" : "\t",
"\\v" : "\v",
"\\0" : "\0",
"\\'" : "\'",
"\\\"" : "\"",
"\\\\" : "\\"
}[seq]))();
Then we can rely on ES6 fromcodepoint to deal with the rest which are all hexadecimals.
const convertEscape = seq => {
if (single.test(seq))
return singleEscape(seq);
else if (uniES6.test(seq))
return String.fromCodePoint(`0x${seq.split("").slice(3, -1).join("")}`);
else
return String.fromCodePoint.apply(
String, seq.split("\\").slice(1).map(pt => `0x${pt.substr(1)}`)
);
}
Lastly, we tie it all together with a tagged template literal function named normal. I do not know why you need a raw string, but here you can have access to the raw string and put any additional logic while still resulting in a string where escape sequences are properly parsed.
const normal = (strings, ...values) => strings.raw
.reduce((acc, cur, i) => acc += (values[i-1] || "") + cur, "")
.replace(escapes, match => convertEscape(match));

Jquery/Javascript remove duplicate parameters in a url string

Here's my url string, I am trying to break down the parameters and get the value for "q" parameter.
a) http://myserver.com/search?q=bread?topic=14&sort=score
b) http://myserver.com/search?q=bread?topic=14&sort=score&q=cheese
how do i use Jquery/JavaScript to get "q" value?
for case a), i can use string split or use jquery getUrlParam to get q value = bread
for case b), when there are duplicates how do i retrieve the q value at the end, when there are multiple "q" params
in pure javascript, try
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)')
.exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
Reference
in jQuery see this plugin
https://github.com/allmarkedup/jQuery-URL-Parser
UPDATE
when u get array of all query string then to remove duplicate from an array via jQuery try unique or see this plugin
http://plugins.jquery.com/plugin-tags/array-remove-duplicates
Here you can use a regular expression. For example, we might have this string:
var str = 'http://myserver.com/search?q=bread&topic=14&sort=score&q=cheese';
Find the search portion of the URL by stripping everything from the beginning to the first question mark.
var search = str.replace(/^[^?]+\?/, '');
Set up a pattern to capture all q=something.
var pattern = /(^|&)q=([^&]*)/g;
var q = [], match;
And then execute the pattern.
while ((match = pattern.exec(search))) {
q.push(match[2]);
}
After that, q will contain all the q parameters. In this case, [ "bread", "cheese" ].
Then you can use any of q.
If you only care about the last one, you can replace the q.push line with q = match[2].
It looks like you can use getUrlParam for both, but you have to handle the second case's return value as an array with multiple values (at least in the getUrlParam code I'm looking at).
getUrlParam('q') should return an array. Try to get those values with this code:
values = $.getUrlParam('q');
// use the following code
first_q_value = values[0];
second_q_value = values[1];

Javascript split only once and ignore the rest

I am parsing some key value pairs that are separated by colons. The problem I am having is that in the value section there are colons that I want to ignore but the split function is picking them up anyway.
sample:
Name: my name
description: this string is not escaped: i hate these colons
date: a date
On the individual lines I tried this line.split(/:/, 1) but it only matched the value part of the data. Next I tried line.split(/:/, 2) but that gave me ['description', 'this string is not escaped'] and I need the whole string.
Thanks for the help!
a = line.split(/:/);
key = a.shift();
val = a.join(':');
Use the greedy operator (?) to only split the first instance.
line.split(/: (.+)?/, 2);
If you prefer an alternative to regexp consider this:
var split = line.split(':');
var key = split[0];
var val = split.slice(1).join(":");
Reference: split, slice, join.
Slightly more elegant:
a = line.match(/(.*?):(.*)/);
key = a[1];
val = a[2];
May be this approach will be the best for such purpose:
var a = line.match(/([^:\s]+)\s*:\s*(.*)/);
var key = a[1];
var val = a[2];
So, you can use tabulations in your config/data files of such structure and also not worry about spaces before or after your name-value delimiter ':'.
Or you can use primitive and fast string functions indexOf and substr to reach your goal in, I think, the fastest way (by CPU and RAM)
for ( ... line ... ) {
var delimPos = line.indexOf(':');
if (delimPos <= 0) {
continue; // Something wrong with this "line"
}
var key = line.substr(0, delimPos).trim();
var val = line.substr(delimPos + 1).trim();
// Do all you need with this key: val
}
Split string in two at first occurrence
To split a string with multiple i.e. columns : only at the first column occurrence
use Positive Lookbehind (?<=)
const a = "Description: this: is: nice";
const b = "Name: My Name";
console.log(a.split(/(?<=^[^:]*):/)); // ["Description", " this: is: nice"]
console.log(b.split(/(?<=^[^:]*):/)); // ["Name", " My Name"]
it basically consumes from Start of string ^ everything that is not a column [^:] zero or more times *. Once the positive lookbehind is done, finally matches the column :.
If you additionally want to remove one or more whitespaces following the column,
use /(?<=^[^:]*): */
Explanation on Regex101.com
function splitOnce(str, sep) {
const idx = str.indexOf(sep);
return [str.slice(0, idx), str.slice(idx+1)];
}
splitOnce("description: this string is not escaped: i hate these colons", ":")

Categories

Resources