Javascript: Get first number substring for each semi-colon separated substring - javascript

I am creating a script of time calculation from MySQL as I don't want to load the scripts on server-side with PHP.
I am getting the data and parsing it using JSON, which gives me a string of values for column and row data. The format of this data looks like:
1548145153,1548145165,End,Day;1548145209,1548145215,End,Day;1548148072,1548148086,End,Day;1548161279,1548161294,End,Day;1548145161,1548145163,End,Day;1548148082,1548148083,End,Day;1548161291,1548161293,End,Day
I need to split this string by semi-colon, and then extract the first VARCHAR number from before each comma to use that in subsequent calculation.
So for example, I would like to extract the following from the data above:
[1548145153, 1548145209, 1548148072, 1548161279, 1548145161, 1548148082, 1548161291]
I used the following type of for-loop but is not working as I wanted to:
for (var i=0; i < words.length; i++) {
var1 = words[i];
console.log(var1);
}
The string and the for-loop together are like following:
var processData = function(data) {
for(var a = 0; a < data.length; a++) {
var obj = data[a];
var str= obj.report // something like 1548145153,1548145165,End,Day;1548145209,1548145215,End,Day;1548148072,1548148086,End,Day;1548161279,1548161294,End,Day;1548145161,1548145163,End,Day;1548148082,1548148083,End,Day;1548161291,1548161293,End,Day
words = str.split(',');
words = str.split(';');
for (var i=0; i < words.length; i++) {
var1 = words[i];
var2 = var1[0];
console.log(var2);
}

Here is an approach based on a regular expression:
const str = "1548145153,1548145165,End,Day;1548145209,1548145215,End,Day;1548148072,1548148086,End,Day;1548161279,1548161294,End,Day;1548145161,1548145163,End,Day;1548148082,1548148083,End,Day;1548161291,1548161293,End,Day";
const ids = str.match(/(?<=;)(\d+)|(^\d+(?=,))/gi)
console.log(ids)
The general idea here is to classify the first VARCHAR value as either:
a number sequence directly preceded by a ; character (see 1 below) or, for the edge case
the very first number sequence of the input string directly followed by a , character (see 2 below).
These two cases are expressed as follows:
Match any number sequence that is preceded by a ; using the negated lookbehind rule: (?<=;)(\d+), where ; is the character that must follow a number sequence \d+ to be a match
Match any number sequence that is the first number sequence of the input string, and that has a , directly following it using the lookahead rule (^\d+(?=,)), where \d+ is the number sequence and , is the character that must directly follow that number sequence to be a match
These building blocks 1 and 2 are combined using the | operator to achieve the final result

First thing is that you override words with the content of str.split(';'), so it won't hold what you expect. To split the string into chunks, split by ; first, then iterate over the resulting array and within the loop, split by ,.
const str= "1548145153,1548145165,End,Day;1548145209,1548145215,End,Day;1548148072,1548148086,End,Day;1548161279,1548161294,End,Day;1548145161,1548145163,End,Day;1548148082,1548148083,End,Day;1548161291,1548161293,End,Day";
const lines = str.split(';');
lines.forEach(line => {
const parts = line.split(',');
console.log(parts[0]);
});

What you are doing is not correct, you'll have to separate strings twice as there are two separators. i.e. a comma and a semicolon.
I think you need a nested loop for that.
var str = "1548145153,1548145165,End,Day;1548145209,1548145215,End,Day;1548148072,1548148086,End,Day;1548161279,1548161294,End,Day;1548145161,1548145163,End,Day;1548148082,1548148083,End,Day;1548161291,1548161293,End,Day"
let words = str.split(';');
for (var i=0; i < words.length; i++) {
let varChars = words[i].split(',');
for (var j=0; j < varChars.length; i++)
console.log(varChars[j]);
}
I hope this helps. Please don't forget to mark the answer.

Related

make array from string by converting datatype using javascript

The string I have is as like as follows
let a = "0j (0.001953125+0j) (-0.001953125+0.001953125j) (0.998046875+0j) (-0.001953125+0j) (0.001953125+0j) (0+0.0914587j)"
Info about the string:
1/ Each substring is complex number in the format of a+bj
2/ Possible format of the complex number could be a+bj,a,bj. Eg: 1+2j, 1,2j
3/ There is a space( ) between each substring
4/ I have seen that 0+bj(eg: 0+5j) or a+0j(eg: 5+0j) format is not possible/ created by the backend so this type of format/ presentation is not considered for my case.
5/ If the substring contains only real/imaginary part then parenthesis () will not be used. Eg: (5),(5j) is not possible. They will be 5,5j
I need to create a JSON or JavaScript object from that string which will be used to plot data. The data is coming from the Flask backend and it is different for each request. One approach I have found to make this JSON object is from an array which should look like
let my_array = [[0,0], [0.001953125,0], [-0.001953125,0.001953125], [0.998046875,0],[-0.001953125,0],[-0.001953125,0],[0,0.914587]]
But I am totally lost in making of this array. Initially, I have removed all the j from the string by a.replaceAll("j","") but then I have not found a way to make my desired array structure. If I get the array, I can make the JSON object with the following approach:
my_array = [[0,0], [0.001953125,0], [-0.001953125,0.001953125], [0.998046875,0],[-0.001953125,0],[-0.001953125,0],[0,0.914587]]
temp_key = ["i", "q"]
my_json = {
}
for(let a = 0; a < my_array.length; a++){
temp_json = {};
for(let b = 0; b < my_array[a].length; b++){
temp_json[temp_key[b]] = my_array[a][b];
}
my_json[String(a)] = temp_json;
}
console.log("my_json: ",my_json)
Suggestions regarding making this array will be appreciated.
You can split by whitespace, then use a regular expression to match digit characters in the substring (eg 0.001953125+0j to 0.001953125 and 0).
const str = "0j (0.001953125+0j) (-0.001953125+0.001953125j) (0.998046875+0j) (-0.001953125+0j) (0.001953125+0j) (0+0.914587j)";
const arr = str
.split(' ')
.map((substr) => {
const [real, imag = 0] = substr.match(/-?\d+(?:\.\d+)?/g).map(Number);
return [real, imag];
});
console.log(arr);
-?\d+(?:\.\d+)? is:
-? - possibly match a leading -
\d+ - match one or more digits
(?:\.\d+)? - optionally match the following (the decimal part of a number):
\. - a literal .
\d+ - one or more digits

Get All possible matches between forward slashes

I would like to get all possible matches of a string with forward slashes '/' using regex.
I would like to regex that matches all the possibilities of a string between slashes but excludes a part which has no ending '/'
For example a string /greatgrandparent/grandparent/parent/child
it should return something like this:
/greatgrandparent/
/greatgrandparent/grandparent/
/greatgrandparent/grandparent/parent/
The following regex that will get each word that begins with a / and a positive lookahead for the / character is this /\/\w+(?=\/)/g
You can use the match() function that will place each word it finds in an array. You can then loop through the array to combine the different results. Check out the snippet below.
var str = `/greatgrandparent/grandparent/parent/child`;
var strArr = str.match(/\/\w+(?=\/)/g);
console.log(strArr);
var strLoop = ``;
for (i = 0; i < strArr.length; i++) {
strLoop += strArr[i];
document.write(`${strLoop}<br>`);
}

Javascript - Using Concatenated String in Regex

I'm trying to find if a given string of digits contains a sequence of three identical digits.
using a for loop, each digit in the string gets its own representation of a three digit sequence which is then checked against the string using Regex:
var str = "6854777322"
for(var i=0; i<str.length; i++)
{
seqToCompare = str[i] + str[i] + str[i];
var re = new RegExp(seqToCompare, "g");
if(str.match(re).length == 1)
{
match = str[i];
}
}
console.log(match)
The result should be seven (if I put 777 in seqToCompare, it would work), but it looks like the concatenation causes it to fail. Console shows "cannot read property length for null".
You can test it here - https://jsfiddle.net/kwnL7vLs/
I tried .toString, setting seqToCompare in Regex format and even parsing it as int (out of desperation for not knowing what to do anymore...)
Rather than looping over each character, you can use a simple regex to get a digit that is repeated 3 times:
/(\d)(?=\1{2})/
(\d) - Here we match a digit and group it in captured group #1
(?=\1{2}) is lookahead that asserts same captured group #1 is repeated twice ahead of current position
RegEx Demo
anubhava's answer is the way to go, as it's more efficient and simpler. However, if you're wondering why your code specifically is giving an error, it's because you try to find the length property of the return value of str.match(), even when no match is found.
Try this instead:
var str = "6854777322"
for(var i=0; i<str.length; i++)
{
seqToCompare = str[i] + str[i] + str[i];
var re = new RegExp(seqToCompare, "g");
if(str.match(re))
{
match = str[i];
}
}
console.log(match)

Javascript respecting backslashes in input: negative lookbehind

In Javascript, I have a situation where I get input which I .split(/[ \n\t]/g) into an array. The point is that if a space is directly preceded by a backslash, I don't want the split to happen there.
E.g. is_multiply___spaced_text -> ['is','multiply','','','spaced','text']
But: is\_multiply\___spaced_text -> ['is multiply ','','spaced','text']
(Underscores used for spaces for clarity)
If this wasn't Javascript (which doesn't support lookbehinds in regex'es), I'd just use /(?<!\\)[ \n\t]/g. That doesn't work, so what would be the best way to handle this?
You can reverse the string, then use negative lookahead and then reverse the strings in the array:
var pre_results = "is\\ multiply\\ spaced text".split('').reverse().join('').split(/[ \t](?!\\)/);
var results = [];
for(var i = 0; i < pre_results.length; i++) {
results.push(pre_results[i].split('').reverse().join(''));
}
for(var i = 0; i < results.length; i++) {
document.write(results[i] + "<br>");
}
In this example, the result should be:
['text', 'spaced', '', 'is\\ multiply\\']
"is\_multiply\___spaced_text".replace(/\_/, " ").replace(/_/, " ").split("_");

URL extraction from string

I found a regular expression that is suppose to capture URLs but it doesn't capture some URLs.
$("#links").change(function() {
//var matches = new array();
var linksStr = $("#links").val();
var pattern = new RegExp("^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$","g");
var matches = linksStr.match(pattern);
for(var i = 0; i < matches.length; i++) {
alert(matches[i]);
}
})
It doesn't capture this url (I need it to):
http://www.wupload.com/file/63075291/LlMlTL355-EN6-SU8S.rar
But it captures this
http://www.wupload.com
Several things:
The main reason it didn't work, is when passing strings to RegExp(), you need to slashify the slashes. So this:
"^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$"
Should be:
"^(https?:\/\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\/\\w \\.-]*)*\/?$"
Next, you said that FF reported, "Regular expression too complex". This suggests that linksStr is several lines of URL candidates.
Therefore, you also need to pass the m flag to RegExp().
The existing regex is blocking legitimate values, eg: "HTTP://STACKOVERFLOW.COM". So, also use the i flag with RegExp().
Whitespace always creeps in, especially in multiline values. Use a leading \s* and $.trim() to deal with it.
Relative links, eg /file/63075291/LlMlTL355-EN6-SU8S.rar are not allowed?
Putting it all together (except for item 5), it becomes:
var linksStr = "http://www.wupload.com/file/63075291/LlMlTL355-EN6-SU8S.rar \n"
+ " http://XXXupload.co.uk/fun.exe \n "
+ " WWW.Yupload.mil ";
var pattern = new RegExp (
"^\\s*(https?:\/\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\/\\w \\.-]*)*\/?$"
, "img"
);
var matches = linksStr.match(pattern);
for (var J = 0, L = matches.length; J < L; J++) {
console.log ( $.trim (matches[J]) );
}
Which yields:
http://www.wupload.com/file/63075291/LlMlTL355-EN6-SU8S.rar
http://XXXupload.co.uk/fun.exe
WWW.Yupload.mil
Why not do make:
URLS = str.match(/https?:[^\s]+/ig);
(https?\:\/\/)([a-z\/\.0-9A-Z_-\%\&\=]*)
this will locate any url in text

Categories

Resources