Grab substring after and before two specific characters in javascript - javascript

i have a url search key like that:
?retailerKey=A and i want to grab the retailerKey substring. All examples that i saw are having as example how to take before the char with the indexOf example. How can i implement this to have this substring from the string ?retailerKey=A

You could split() the string on any ? or = and take the middle item ([1]) from the outcome array.
const data = "?retailerKey=A";
const result = data.split(/[\?=]/)[1];
console.log(result);
If you have multiple params, creating an object fromEntries() would be interesting.
const data = "?retailerKey=A?otherKey=B";
const keyVals = data.split(/[\?=]/).filter(x => x); // keys and values
const result = Object.fromEntries(keyVals.reduce((acc, val, i) => {
// create entries
const chunkI = Math.floor(i / 2);
if (!acc[chunkI]) acc[chunkI] = [];
acc[chunkI].push(val);
return acc;
}, []));
console.log(result);

use regex expression.
Following will return the value between character ? and =
var result = "?retailerKey=A".match(/\?(.*)\=/).pop();
console.log(result);

If you would like to always get the string between your query sign and equal sign ?ThisString=
then you can simply use indexOf for example
str.slice(str.indexOf('?')+1,str.indexOf('='))

Using library could be a better choice but to do it from scratch : I suggest to use split with a regular expression.
// split for char equals to ? or & or =;
const url = '/toto?titi=1&tata=2';
const args = url.split(/[\?\&\=]/);
// shift the first element of the list since it the base url before "?"
args.shift();
// detect malformed url
if (args.length % 2) {
console.error('malformed url', args);
}
const dictArgs = {};
for (let i = 0; i < args.length /2; i ++) {
const key = args[2*i];
const val = args[2*i+1];
dictArgs[key] = val;
}
console.log(dictArgs);

Related

How to proper use reduce() javascript/typescript

I try to solve task below with reduce() and actually the result is ok. But I don't know how to use acc in reduce() instead of acc1 or indexMax.
How to apply typescript to this task.
The task:
Find first word with max repeated letter count. For example rrrtygggg and ttbvfddjklyyyaseqq - the winner is rrrtygggg.
If sequence has no repeated letters return 'false'.
Count only letters, ignor digits and special chars.
Here is my solution.
Also I need to keep time complexity not higher than n. The most important part for me is reduce() and acc.
const maxLettersInString =(str)=>{
let acc1={};
let indexMax;
let ind=0;
let n=0;
const newStr = str.replace(/[^a-z\s]/gi,'')
const arr = str.split(' ');
if(arr.length===0) return false;
const arr1 = newStr.split('');
const result = arr1.reduce((acc,x)=>{
if(x!==' '){
acc1[x] ? acc1[x]++ : acc1[x] = 1;
if(acc1[x]>n) n=acc1[x], indexMax=ind;
}
if(x===' ') acc1={}, ind+=1;
else return indexMax;
})
if(n===1) return false
return arr[result]
}
console.log(maxLettersInString('fdsJJHHBldfkfd +=dfsfds tbrlllLLtrbtrbrLL666667777LLtlllllll----- fdsfs66df7758 tRbrerbrrtRR'));
Iterate over the original words, with two outer variables:
One with a count of the maximum number of repeated letters found so far (starts at 0), and
The string corresponding to the count found above
All you need is a simple loop - on each iteration, calculate the repeat count for the current word being iterated over, and if it's higher than the record so far, reassign the two outer variables.
const getRepeatCount = (str) => {
const repeatCounts = {};
for (const char of str.replace(/[^a-z]/gi, '')) {
repeatCounts[char] = (repeatCounts[char] ?? -1) + 1;
}
return Math.max(...Object.values(repeatCounts));
};
const maxLettersInString = (str) => {
let maxRepeatsFoundSoFar = 0;
let bestWordSoFar = '';
for (const word of str.split(' ')) {
const repeatCount = getRepeatCount(word);
if (repeatCount > maxRepeatsFoundSoFar) {
maxRepeatsFoundSoFar = repeatCount;
bestWordSoFar = word;
}
}
return bestWordSoFar === '' ? false : bestWordSoFar;
};
console.log(maxLettersInString('rrrtygggg and ttbvfddjklyyyaseqq'));
To turn it into TypeScript, just add : string to the parameter types and : Record<string, number> to the repeatCounts object.
This would be possible to do with .reduce if the accumulator was an object with two properties, maxRepeatsFoundSoFar and bestWordSoFar instead of outer variables - but the typing and syntax noise would be annoying, outer variables are easier.

How can I iterate text from a character to another character using Javascript?

Given a url as following :
https://website.com/demo?name=helloworld&timestamp=1234567890
How can I iterate from the = sign and the & sign, resulting in helloworld in JS?
Thanks in advance. :)
1) Though you don't need to iterate here. You can use slice here to get a part of a string
const str = "https://website.com/demo?name=helloworld&timestamp=1234567890";
const start = str.indexOf("=");
const end = str.indexOf("&");
const result = str.slice(start + 1, end);
console.log(result);
2) If you still want to iterate over from = and upto & then you can do
const str = "https://website.com/demo?name=helloworld&timestamp=1234567890";
const end = str.indexOf("&");
const resultArr = [];
for (let start = str.indexOf("=") + 1; start < end; ++start) {
resultArr.push(str[start]);
}
console.log(resultArr.join(""));
3) You can also use regex here
(?<==)\w+
const str = "https://website.com/demo?name=helloworld&timestamp=1234567890";
const match = str.match(/(?<==)\w+/);
console.log(match[0]);
Important note: You can apply this method if you are sure that there is only one "=" and "&" and the text that you want is between them. If that is not the case you will have to search the whole string.
Explanation:
str.indexOf('=') + 1 // will result 30
str.indexOf('&') // will result 40
So, str.slice(30, 40) will give the substring from 30th position to 39th position, it will ignore the 40th position.
let str = 'https://website.com/demo?name=helloworld&timestamp=1234567890'
//1. Find the index of "=" + 1, because slice selects the starting argument.
let subStr = str.slice(str.indexOf('=') + 1, str.indexOf('&'))
console.log(subStr)
You can also utilise regex to figure that out,
const extractStringBetween = (char1,char2) => (str) => str.match(RegExp(`${char1}([^${char1}${char2}]+)${char2}`))[1]
console.log(extractStringBetween('=','&')('https://website.com/demo?name=helloworld&timestamp=1234567890'))
This uses group capture.
You can learn more at https://regexr.com/

Dynamic masked input according to data [duplicate]

This question already has answers here:
Dynamic regex pattern in JavaScript
(4 answers)
Closed 2 years ago.
I have a response and it returns "XXX-XXX" or "XX-XXXX"
const formatUnitCode = (value, format) => {}
So basically, I want to see as formatUnitCode("123456", "XX-XXX") --> "12-3456"
I don't want to use if else because it may come in the future as XX-XX-XX
Can someone help me create this function?
I tried to do with regex but I think it is not possible to pass variable instead of {2} and {4}
const formatCode = (val) => val.replace(/(\d{2})(\d{4})/g, "$1-$2");
Is this what you would like to do?
const func = (val, first_digit) => {
let regex = new RegExp("(\\d{" + first_digit + "})(\\d{" + (6-first_digit) + "})","g");
return val.replace(regex,"$1-$2");
};
You can use simple for loop make a dynamic string format method.
const formatUnitCode = (str, format) => {
let result = '';
let j = 0;
for (let i = 0, l = format.length; i < l; i += 1) {
if (format[i] === 'X') {
result += str[j];
j += 1;
} else result += format[i];
}
for (; j < str.length; j += 1) result += str[j];
return result;
};
console.log(formatUnitCode('123456', 'XX-XXX'));
console.log(formatUnitCode('123456', 'XXX-XXX'));
console.log(formatUnitCode('123456', 'XX-XXXX'));
console.log(formatUnitCode('123456', 'XX-XX-XX'));
You can't use variables in RegExp literals, but you can when you use the RegExp() constructor to build the pattern as a string instead.
const formatStr = (val, format) => {
let ptn = format.split('-').map(part => '(.{'+part.length+'})').join('');
match = val.match(new RegExp(ptn));
match && console.log(match.slice(1).join('-'));
};
It's instructive to console.log() the ptn var to see what's happening there. We're using your arbitrary "X"-based format to derive a new, dynamic RegExp which will be used in a multi-match RegExp to grab the parts.
formatStr('123456', 'xxx-xxx'); //"123-456"
formatStr('123456', 'xx-xxxx'); //"12-3456"
This should work for any mask regardless of the letters used (you can control that behaviour by changing matcher regex). Personally, I think it's a more elastic approach than just trying to match the given mask with a regex.
const replaceWithFiller = (filler, str, matcher = /[a-zA-z]/g) => {
const arr = filler.split('');
return str.replace(matcher, () => arr.shift());
};
console.log(replaceWithFiller('123456', 'XXX-XXX')); //"123-456"
console.log(replaceWithFiller('123456', 'XX-XX-XX')); // "12-34-56"
console.log(replaceWithFiller('123456', 'XX-XXXX')); //"12-3456"
console.log(replaceWithFiller('123456', 'aa-aaaa')); // also "12-3456"
you can pass parameters to your regex using template literals:
const formatCode = (val, format) => {
const lengthFirstBlock = format.indexOf('-');
const lehgthSecondBlock = format.length - format.indexOf('-');
const regex = new RegExp(`(\\d{${lengthFirstBlock}})(\\d{${lehgthSecondBlock}})`, 'g');
return val.replace(regex, "$1-$2");
}
console.log(formatCode("123456", "XX-XXX"))
console.log(formatCode("123456", "XXX-XX"))

Search Placeholder Values in 2 strings

I've two strings in JavaScript like
var description = "<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>"
var Title = "<DP_A>.<Del.Dce Lks.1>.<Pl.Rrs Bk 0.310-PT-304_(1)>"
here {Link} and {strm} are placeholders or more likely whatever comes between { } is placeholder
I need to compare both string like description and Title to find placeholder values, Output needs to be like
{"Link" : 1, "strm" : 1 }
or array
[{Link" : 1, "strm" : 1}]
I've tried some RegEx but not working, any help??
if (description.includes("{")) {
var found = [], // an array to collect the strings that are found
rxp = /{([^}]+)}/g,
curMatch;
while (curMatch = rxp.exec(description)) {
found.push(curMatch[1]);
}
}
I'm able to get array of Placeholders but not able to find values into title string.
You could get all parts and then splice the values out of the title string.
"<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>",
"<DP_A>.<Del.Dce Lks. 1 >.<Pl.Rrs Bk 0.310-PT-304_( 1 )>";
function getParts(pattern, values) {
var result = {}, value, p1, p2 = 0;
(pattern.match(/[^{}]+/g) || []).forEach((s, i, a) => {
if (i % 2) return Object.assign(result, { [s]: value });
p1 = values.indexOf(s, p2),
p2 = values.indexOf(a[i + 2], p1);
value = values.slice(p1 + s.length, p2 === -1 ? undefined : p2);
});
return result;
}
var description = "<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>{last}",
title = "<DP_A>.<Del.Dce Lks.abcdef>.<Pl.Rrs Bk 0.310-PT-304_(ghijklöööö)>fubar";
console.log(getParts(description, title));
With a for statement and reusing known positions.
function getParts(pattern, values) {
var parts = pattern.match(/[^{}]+/g),
result = {}, p1, p2, i;
if (!parts || parts.length < 2) return {};
p1 = values.indexOf(parts[0]);
for (i = 1; i < parts.length; i += 2) {
p2 = values.indexOf(parts[i + 1], p1);
Object.assign(result, { [parts[i]]: values.slice(p1 + parts[i - 1].length, p2 === -1 ? undefined : p2) });
p1 = p2;
}
return result;
}
var description = "<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>{last}",
title = "<DP_A>.<Del.Dce Lks.abcdef>.<Pl.Rrs Bk 0.310-PT-304_(ghijklöööö)>fubar";
console.log(getParts(description, title));
Use replace:
var description = "<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>"
const obj = {
Link: 1,
strm: 2
};
const res = description.replace(/{(.*?)}/g, m => obj[m.slice(1, -1)]);
document.write(res);
Okay, this is far more complex than I actually expected.
I'm not actually that good at this kind of operations, but here is a "working" solution: you may want to rewrite it a bit, but still, the concept is actually fair to me.
The steps followed to achieve the results are:
Acquire all the indexes of "{". I've used a function generator below, but you may use whathever other criteria you want. The goal is to acquire the starting bracket of each match.
loop each matched bracket, look for the closing bracket and acquire the character just after it in the description string.
perform the value match upon the Title string.
Continue by applying currently matched values to update the offsets.
Map the result to collect the desired output: I've intentionally returned an array of items because a placeholder may exist twice.
Some side notes:
The below script, as mentioned above, won't take care of limit cases like "{hello{world}".
The below script can be improved by matching both the previous character and the next character.
The below script might fail in some situations, it just happens to work in this case, but I didn't test it with limit cases.
var description = "<DP_A>.<Del.Dce Lks.{Link}>.<Pl.Rrs Bk 0.310-PT-304_({strm})>";
var Title = "<DP_A>.<Del.Dce Lks.1>.<Pl.Rrs Bk 0.310-PT-304_(1)>";
// Acquire all the indexes of every "{".
// BEWARE: This will actually fail if the description is "&LT{LLT{hello}", but you may change this.
const descriptionLookupIndexes = [].concat(...(function*(){
for (var i = 0; i < description.length; i++) {
if (description[i] === "{") yield [i];
}
})());
let matches = [];
descriptionLookupIndexes.forEach((i, index) => {
// acquire the description by replacing the currently known values.
let _replacedDescription = description;
let _replacedDescriptionIndex = i - matches.reduce((a,b) => a + b.amount, 0);
// This foreach will replace the placeholders already found with their respective values.
matches.forEach(k => {
let splitted = _replacedDescription.split('');
splitted.splice(k.from, k.amount, [k.value.split('')]);
_replacedDescription = splitted.join('');
});
// Acquire the relevant portion of the string.
const needle = _replacedDescription.substring(_replacedDescriptionIndex, _replacedDescription.length);
// Look for the next character after the first } occurrence in the current substring.
const nextChar = needle[needle.indexOf("}") + 1];
// Acquire the relevant substring for the title.
const titleNeedle = Title.substring(_replacedDescriptionIndex, Title.length);
matches.push({
from: _replacedDescriptionIndex,
amount: needle.match(/[^{\}]+(?=})/g)[0].length + 1,
needle: needle.match(/[^{\}]+(?=})/g)[0],
value: titleNeedle.substring(0, titleNeedle.indexOf(nextChar))
});
});
// Matches is now the array with all the occurrences, let's just map it to acquire a new array of objects with the desired format.
// BEWARE: If multiple keys exists, they will be mapped to an array.
const res = matches.reduce((acc, next) => {
acc[next.needle] = acc[next.needle] || [];
acc[next.needle].push({
[next.needle]: next.value
});
return acc;
}, {});
console.log(res);

Javascript Equivalent to PHP Explode()

I have this string:
0000000020C90037:TEMP:data
I need this string:
TEMP:data.
With PHP I would do this:
$str = '0000000020C90037:TEMP:data';
$arr = explode(':', $str);
$var = $arr[1].':'.$arr[2];
How do I effectively explode a string in JavaScript the way it works in PHP?
This is a direct conversion from your PHP code:
//Loading the variable
var mystr = '0000000020C90037:TEMP:data';
//Splitting it with : as the separator
var myarr = mystr.split(":");
//Then read the values from the array where 0 is the first
//Since we skipped the first element in the array, we start at 1
var myvar = myarr[1] + ":" + myarr[2];
// Show the resulting value
console.log(myvar);
// 'TEMP:data'
String.prototype.explode = function (separator, limit)
{
const array = this.split(separator);
if (limit !== undefined && array.length >= limit)
{
array.push(array.splice(limit - 1).join(separator));
}
return array;
};
Should mimic PHP's explode() function exactly.
'a'.explode('.', 2); // ['a']
'a.b'.explode('.', 2); // ['a', 'b']
'a.b.c'.explode('.', 2); // ['a', 'b.c']
You don't need to split. You can use indexOf and substr:
str = str.substr(str.indexOf(':')+1);
But the equivalent to explode would be split.
Looks like you want split
Try this:
arr = str.split (":");
create's an object :
// create a data object to store the information below.
var data = new Object();
// this could be a suffix of a url string.
var string = "?id=5&first=John&last=Doe";
// this will now loop through the string and pull out key value pairs seperated
// by the & character as a combined string, in addition it passes up the ? mark
var pairs = string.substring(string.indexOf('?')+1).split('&');
for(var key in pairs)
{
var value = pairs[key].split("=");
data[value[0]] = value[1];
}
// creates this object
var data = {"id":"5", "first":"John", "last":"Doe"};
// you can then access the data like this
data.id = "5";
data.first = "John";
data.last = "Doe";
Use String.split
"0000000020C90037:TEMP:data".split(':')
If you like php, take a look at php.JS - JavaScript explode
Or in normal JavaScript functionality:
`
var vInputString = "0000000020C90037:TEMP:data";
var vArray = vInputString.split(":");
var vRes = vArray[1] + ":" + vArray[2]; `
console.log(('0000000020C90037:TEMP:data').split(":").slice(1).join(':'))
outputs: TEMP:data
.split() will disassemble a string into parts
.join() reassembles the array back to a string
when you want the array without it's first item, use .slice(1)
With no intentions to critique John Hartsock, just in case the number of delimiters may vary for anyone using the given code, I would formally suggest to use this instead...
var mystr = '0000000020C90037:TEMP:data';
var myarr = mystr.split(":");
var arrlen = myarr.length;
var myvar = myarr[arrlen-2] + ":" + myarr[arrlen-1];
var str = '0000000020C90037:TEMP:data'; // str = "0000000020C90037:TEMP:data"
str = str.replace(/^[^:]+:/, ""); // str = "TEMP:data"
Just a little addition to psycho brm´s answer (his version doesn't work in IE<=8).
This code is cross-browser compatible:
function explode (s, separator, limit)
{
var arr = s.split(separator);
if (limit) {
arr.push(arr.splice(limit-1, (arr.length-(limit-1))).join(separator));
}
return arr;
}
I used slice, split and join
You can just write one line of code
let arrys = (str.split(":").slice(1)).join(":");
So I know that this post is pretty old, but I figured I may as well add a function that has helped me over the years. Why not just remake the explode function using split as mentioned above? Well here it is:
function explode(str,begin,end)
{
t=str.split(begin);
t=t[1].split(end);
return t[0];
}
This function works well if you are trying to get the values between two values. For instance:
data='[value]insertdataherethatyouwanttoget[/value]';
If you were interested in getting the information from between the two [values] "tags", you could use the function like the following.
out=explode(data,'[value]','[/value]');
//Variable out would display the string: insertdataherethatyouwanttoget
But let's say you don't have those handy "tags" like the example above displayed. No matter.
out=explode(data,'insert','wanttoget');
//Now out would display the string: dataherethatyou
Wana see it in action? Click here.
var str = "helloword~this~is~me";
var exploded = str.splice(~);
the exploded variable will return array and you can access elements of the array be accessing it true exploded[nth] where nth is the index of the value you want to get
try like this,
ans = str.split (":");
And you can use two parts of the string like,
ans[0] and ans[1]
If you want to defined your own function, try this:
function explode (delimiter, string, limit) {
if (arguments.length < 2 ||
typeof delimiter === 'undefined' ||
typeof string === 'undefined') {
return null
}
if (delimiter === '' ||
delimiter === false ||
delimiter === null) {
return false
}
if (typeof delimiter === 'function' ||
typeof delimiter === 'object' ||
typeof string === 'function' ||
typeof string === 'object') {
return {
0: ''
}
}
if (delimiter === true) {
delimiter = '1'
}
// Here we go...
delimiter += ''
string += ''
var s = string.split(delimiter)
if (typeof limit === 'undefined') return s
// Support for limit
if (limit === 0) limit = 1
// Positive limit
if (limit > 0) {
if (limit >= s.length) {
return s
}
return s
.slice(0, limit - 1)
.concat([s.slice(limit - 1)
.join(delimiter)
])
}
// Negative limit
if (-limit >= s.length) {
return []
}
s.splice(s.length + limit)
return s
}
Taken from: http://locutus.io/php/strings/explode/

Categories