Test and read variables from file with JS/NodeJS - javascript

I am creating a script which is able to read an environment file. The content can be as following:
var1 = 'test'
var2='test2'
var1= 'test'
var3 = 4
I would like to extract the key and the value, eg.:
var1 = 'test' -> result[0]: var1, result[1]: test
How can i write a function that can test if the line read with readFile is valid and afterwards its key (eg. var1) and value (eg. test)? Is it possible to extract both key and value with regexp without running two regexp functions?

Once you have your line stored, you can do something like this:
// line is the line you are processing, object is where you save your stuff
function processLine(line, object) {
var parts = line.split("=");
if (parts.length<2)
return;
// key is parts[0], value is parts[1]
var key = parts.shift();
// if we have equal signs in our value, they will be preserved
var value = parts.join("=");
// get rid of any trailing or preceding spaces
key = key.trim();
value = value.trim();
// is the value a quoted string?
if ((value.charAt(0)==="'" && value.charAt(value.length-1)==="'") ||
(value.charAt(0)==='"' && value.charAt(value.length-1)==='"'))
value = value.slice(1, value.length-1);
// otherwise we assume it's a number
else
value = parseFloat(value);
// TODO: you can check for other stuff here, such as 'true', 'false' and 'null'
// finally, assign it to your object
object[key] = value;
}
Now you just need to call your function for each line, for instance:
var values = {};
for (var i in lines)
processLine(lines[i], values);
Caveats of this approach are numerous. They are easily fixed with some extra code, but I would recommend using something like JSON for defining your configuration values (if that is what they are). There is native support for JSON parsing in javascript, so you could just use that. Maybe you should reconsider your approach.

You can try the following JS code:
function validate(str)
{
var re = /^(\w+)\s*\=\s*(['"]?)(.*?)\2$/;
if ((m = re.exec(str)) !== null) {
return [m[1], m[3]];
}
}
document.getElementById("res").innerHTML =
"Result [0]: " + validate("var1 = 'test'")[0] + "<br>Result [1]: " + validate("var1 = 'test'")[1];
<div id="res"/>

Read the line.. replace quotes with null
//line = "var1 = 'test'";
line = line.replace(/'/g, "");
Split by delimiter =
var result = line.split("=");
//result is an array containing "var1" and "test"
line = "var1 = 'test'";
line = line.replace(/'/g, "");
var result = line.split("=");
document.write("key => "+result[0].trim());
document.write(": value => "+result[1].trim());

Related

How to make separator between values from different select options?

I've got this:
function generate() {
var color = $("#color option:selected").map(function(){return this.value}).get().join('-');
var size = $("#size option:selected").map(function(){return this.value}).get().join('-');
// Final URL
var result = 'https://weneve.com/en/59-wall-concrete-tiles?q=';
color ? result += 'Color-'+color : null;
size ? result += 'Size-'+size : null;
window.open(result,'_blank');
}
But in the FINAL URL if someone chooses Value=Color and Value=Size the values are next to each other without any space. How can I separate them with a comma?
Editing answer as recommended... As other follow-on answers have commented, we generally use array.join to handle this kind of stuff. But if you are only ever going to have 2 parameters (color and size) then you could just add the comma if both color and size were selected by the user. The code below just adds one additional statement using the same ternary operator format you used for color and size options with the exception that the condition check is for both (color && size). If both evaluate to true, then add the comma to the result string.
// Final URL
var result = 'https://weneve.com/en/59-wall-concrete-tiles?q=';
color ? result += 'Color-'+color : null;
(color && size) ? result += ',' : null;
size ? result += 'Size-'+size : null;
Instead of concat immediately you can keep you query params in array. Than - concat it with join method.
var queryParams = [];
if(color) queryParams.push('Color-' + color);
if(size) queryParams.push('Size-' + size);
var queryParamsString = queryParams.join(',');
var url = 'https://weneve.com/en/59-wall-concrete-tiles';
var finalUrl = queryParamsString ? url + '?q=' + queryParamsString : url;
But if I were you I would have a look to the URL type https://developer.mozilla.org/en-US/docs/Web/API/URL to construct more understandable and elegant code.
Think about it this way: when working with a list of things where you don't yet know the final length, put those things in an Array. When you're ready to display text that depends on the things that are in that array, then convert the array to a String, with your desired character(s) between the things.
You're already using .join() earlier in your code. You'll use that to add commas in your last step.
function generate() {
// create empty array
var queryParams = [];
var color = $("#color option:selected").map(function(){
return this.value
}).get().join('-');
if (color) {
queryParams.push(color);
}
var size = $("#size option:selected").map(function(){
return this.value
}).get().join('-');
if (size) {
queryParams.push(size);
}
// Final URL
var urlOptions = queryParams.join(',');
var result = `https://weneve.com/en/59-wall-concrete-tiles?q=${params}`;
window.open(result,'_blank');
}

Converting a badly stringfied json to a json object

I have some data i am pulling from a web service. This is the string
(Body:'3886' MessageProperties [headers={}, timestamp=null,
messageId=null, userId=null, receivedUserId=null, appId=null,
clusterId=null, type=null, correlationId=null,
correlationIdString=null, replyTo=null,
contentType=application/x-java-serialized-object,
contentEncoding=null, contentLength=0, deliveryMode=null,
receivedDeliveryMode=PERSISTENT, expiration=null, priority=0,
redelivered=false, receivedExchange=,
receivedRoutingKey=bottomlesspit, receivedDelay=null, deliveryTag=62,
messageCount=0, consumerTag=amq.ctag-sCwfLaMEqWp2GkFwFrY1yg,
consumerQueue=bottomlesspit])
It looks like json but the key value pairs are almost fine but the most important key which is Body isn't like other keys as the string would tell.
I need to read the value of Body and be able to get the value like this
console.log(d.body);
//This above outputs the string as shown
obj = eval('{' + d.body + '}');
console.log(obj);
var match = "Body";
var val = obj.find( function(item) { return item.key == match } );
console.log(val);
How can i read the value of the key Body?.
Use this regular expression instead of a match Body:
\bBody:'(\d*)'
This will catch the Body number in group 1.
You can write a parser function get string and extract values. A very simple function is here. You can modify it also for all exceptions exist.
var str = `(Body:'3886' MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null, correlationIdString=null, replyTo=null, contentType=application/x-java-serialized-object, contentEncoding=null, contentLength=0, deliveryMode=null, receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=bottomlesspit, receivedDelay=null, deliveryTag=62, messageCount=0, consumerTag=amq.ctag-sCwfLaMEqWp2GkFwFrY1yg, consumerQueue=bottomlesspit])`;
function f(inp) {
var index = str.indexOf(inp),
endIndex;
for(var i = index; i < str.length; i ++) {
if(str[i] == ',') {
endIndex = i;
break;
}
}
var output = str.substr(index, endIndex).split('=');
return output;
}
console.log(f('consumerQueue'));
Why not use a regex to match and extract the Body.
Example:
const match = d.body.match(/Body:\'(.+)\'/)
if (match) {
const body = match[1] // This is the value of Body
} else {
// Unable to find Body, handle it here
}

Get multiple values from hash in URL

www.domain.com/lookbook.html#look0&product1
On page load I would like to grab the whole hash ie. #look0&product1
then split it up and save the number of the look ie 0 in a variable called var look and the number of the product ie 1 in another variable called var product. Not sure how to achieve this.
Is this also the best way of passing and retrieving such parameters? Thanks
Use var myHash = location.hash to get hash part of URL. Than do var params = myHash.split('&') and after that for each part do part.split('=') to get key-value pairs.
Maybe it's better to pass these parameters via GET from PHP side and than post them inside page when page is processed via PHP?
<input type="hidden" name="look" value="<?php echo isset($_GET['look']) ? $_GET['look'] : '';?>"/>
Here's the pure Javascript method:
function parseHash(hash) {
// Remove the first character (i.e. the prepended "#").
hash = hash.substring(1, hash.length);
// This is where we will store our properties and values.
var hashObj = {};
// Split on the delimiter "&" and for each key/val pair...
hash.split('&').forEach(function(q) {
// Get the property by splitting on all numbers and taking the first entry.
var prop = q.split(/\d/)[0];
// Get the numerical value by splitting on all non-numbers and taking the last entry.
var val_raw = q.split(/[^\d]/);
var val = val_raw[val_raw.length - 1]
// If the property and key are defined, add the key/val pair to our final object.
if (typeof prop !== 'undefined' && typeof val !== 'undefined') {
hashObj[prop] = +val;
}
});
return hashObj;
}
Use like:
parseHash(window.location.hash /* #book10&id1483 */)
/* returns: Object {book: 10, id: 1483} */
I suggest using the norm for passing values through the location's hash: prop=value. Ex: #book=10&id=311. Then you can easily split on = for each property.
You can use .match(re) method with use of regular expression to extract the number from the given string.
You can try this:
var hashes = location.hash.split('&'); // get the hash and split it to make array
var values = hashes.map(function(hash){ // use .map to iterate and get a new array
return hash.match(/\d+/)[0]; // returns the numbers from the string.
});
var loc = "look0345345345&product1";
var hashes = loc.split('&');
var values = hashes.map(function(hash){ return hash.match(/\d+/)[0]; });
document.body.innerHTML = '<pre>'+ JSON.stringify(values) + '</pre>';
You could try this:
var url = 'www.domain.com/lookbook.html#look0&product1'
, result = {}
, expr = RegExp(/[#&]([a-zA-z]+)(\d+)/g);
var parts = expr.exec(url);
while(parts != null && parts.length == 3) {
result[parts[1]] = parts[2];
parts = expr.exec(url);
}
var look = result['look']
, product = result['product'];
document.getElementById('result').innerHTML = 'look = ' + look + '<br>' + 'product = ' + product;
<p id='result'></p>
We are basically using a regular expression to divide the parameter name and value into two groups that we can then get by calling expr.exec(url).
Each time we call expr.exec(url), we get the next set of name and value groups.
We set the value of the parameter to its name in the result object.
In the regular expression /[#&]([a-zA-z]+)(\d+)/g, the g after the /.../ means match each time find the two groups.
The two groups are prefaced by either & or # ([#&]). The first group is a String of letters ([a-zA-z]+), the name of the parameter. The second is a String of numbers (\d+), the value you are looking for.
The regex returns the String that matches the pattern as the first result in the parts array, followed by the groups matched, which which means that our two groups in each iteration will be parts[1] and parts[2].
you should use:
function parseHash(hash){
hash = hash.substring(1, hash.length); //remove first character (#)
var obj ={}; //create the output
var qa = hash.split('&'); //split all parameters in an array
for(var i = 0; i < qa.length; i++){
var fra1 = qa[i].split('='); //split every parameter into [parameter, value]
var prop = fra1[0];
var value = fra1[1];
if(/[0-9]/.test(value) && !isNaN(value)){ //check if is a number
value = parseInt(value);
}
obj[prop] = value; //add the parameter to the value
}
return obj;
}
document.querySelector("input.hash").onkeyup = function(){
console.log( parseHash(document.querySelector("input.hash").value));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="hash"/>
<p class="output"></p>
use as
parseHash(location.hash /* #look=0&product=1 );
/returns {look: 0, product: 1}/

How Do I Parse a Pipe-Delimited String into Key-Value Pairs in Javascript

I want to parse the following sort of string into key-value pairs in a Javascript object:
var stringVar = 'PLNC||0|EOR|<br>SUBD|Pines|1|EOR|<br>CITY|Fort Myers|1|EOR|<br>';
Each word of 4 capital letters (PLNC, SUBD, and CITY) is to be a key, while the word(s) in the immediately following pipe are to be the value (the first one, for PLNC, would be undefined, the one for SUBD would be 'Pines', the one for CITY would be 'Fort Myers').
Note that '|EOR|' immediately precedes every key-value pair.
What is the best way of doing this?
I just realised it's technically a csv format with interesting line endings. There are limitations to this in that your variable values cannot contain any | or < br> since they are the tokens which define the structure of the string. You could of course escape them.
var stringVar = 'PLNC||0|EOR|<br>SUBD|Pines|1|EOR|<br>CITY|Fort Myers|1|EOR|<br>';
function decodeString(str, variable_sep, line_endings)
{
var result = [];
var lines = str.split(line_endings);
for (var i=0; i<lines.length; i++) {
var line = lines[i];
var variables = line.split(variable_sep);
if (variables.length > 1) {
result[variables[0]] = variables[1];
}
}
return result;
}
var result = decodeString(stringVar, "|", "<br>");
console.log(result);
If you have underscore (and if you don't, then just try this out by opening up your console on their webpage, because they've got underscore included :)
then play around with it a bit. Here's a start for your journey:
_.compact(stringVar.split(/<br>|EOR|\|/))
Try
function parse(str) {
var str = str.replace(/<br>/gi);
console.log(str);
var arr = str.split('|');
var obj = {};
for (var i=0; i<arr.length; i=i+4) {
var key = arr[i] || '';
var val_1 = arr[i+1] || '';
var val_2 = arr[i+2] || '';
if(key) {
obj[key] = val_1 + ':' + val_2; //or similar
}
}
return obj;
}
DEMO
This will work on the particular data string in the question.
It will also work on other data string of the same general format, but relies on :
<br> being discardable before parsing
every record being a group of 4 string elements delineated by | (pipe)
first element of each record is the key
second and third elements combine to form the value
fourth element is discardable.

get the value of a query string item in a url using regex for javascript

I have a URL that includes a product ID which can be in the following format:
One alphabetical letter followed by a number of any number of digits, then an underscore, and then any number of digits and underscores.
So this is a valid product id: c23_02398105 and so is this: c23_02398105_9238714.
Of course in a URL, it's sandwiched between other query string items, so in this url, i want to extract just the id:
http://www.mydomain.com/product.php?action=edit&id=c23_02398105&side=1
I've been trying a regex something along the lines of this, to no avail:
/&id=[a-z]_[(0-9)*]&/
What's the correct way to extract the product id?
function qry(sr) {
var qa = [];
for (var prs of sr.split('&')) {
var pra = prs.split('=');
qa[pra[0]] = pra[1];
}
return qa;
}
var z = qry('http://example.com/product.php?action=edit&id=c23_02398105&side=1');
z.id; // c23_02398105
Source
The below returns an array of values for each key, so if you wanted to get a string for the below, join the values with some delimiter (eg params.id.join(',')) to get your comma-delimited string of IDs.
See Fiddle
http://someurl.com?key=value&keynovalue&keyemptyvalue=&&keynovalue=nowhasvalue#somehash
Handles:
Regular key/value pair (?param=value)
Keys w/o value (?param : no equal sign or value)
Keys w/ empty value (?param= : equal sign, but no value to right of equal sign)
Repeated Keys (?param=1&param=2)
Removes Empty Keys (?&& : no key or value)
Code:
function URLParameters(_querystring){
var queryString = _querystring || window.location.search || '';
var keyValPairs = [];
var params = {};
queryString = queryString.replace(/^[^?]*\?/,''); // only get search path
if (queryString.length)
{
keyValPairs = queryString.split('&');
for (pairNum in keyValPairs)
{
if (! (!isNaN(parseFloat(pairNum)) && isFinite(pairNum)) ) continue;
var key = keyValPairs[pairNum].split('=')[0];
if (!key.length) continue;
if (typeof params[key] === 'undefined')
params[key] = [];
params[key].push(keyValPairs[pairNum].split('=')[1]);
}
}
return params;
}
How to Call:
var params = URLParameters(<url>); // if url is left blank uses the current page URL
params.key; // returns an array of values (1..n) for the key (called 'key' here)
Example Output for Given Keys ('key','keyemptyvalue','keynovalue') using Above URL:
key ["value"]
keyemptyvalue [""]
keynovalue [undefined, "nowhasvalue"]
You can use JavaScript string functions instead of regexp like this:
var url = "http://www.example.com/product.php?action=edit&id=c23_02398105&side=1";
var idToEnd = url.substring(url.search("&id")+4, url.length);
var idPure = idToEnd.substring(0, idToEnd.search("&"));
alert(idPure);
the output is c23_02398105
The following expression fits your description
/&id=([a-z]\d*_[\d_]*)/
It assumes that the letter is lower-case, and that there is only one id in the url in the specified format, or that the one you want is the first one.
var url =
'http://www.mydomain.com/product.php?action=edit&id=c23_02398105&side=1';
var m = url.match( /&id=([a-z]\d*_[\d_]*)/ );
console.log( m && m[1] ); // 'c23_02398105'

Categories

Resources