Convert Javascript string to literal array - javascript

In python there exists ast.literal_eval(x) where if x is "['a','b','c']" then it will return the list ['a','b','c']. Does something similar exist in Javascript / jQuery where I can take the array that is stored in the table cell as [x,y,z] and turn that into a literal JavaScript array?
I'd prefer to avoid any complex solutions that might be error prone since it's possible that involve splitting on the comma or escaping characters.
Edit: I should have given some better examples:
['la maison', "l'animal"] is an example of one that hits an error because doing a replace of a single or double quote can cause an issue since there's no guarantee on which one it'll be.

One could leverage String.prototype.replace() and JSON.parse().
See below for a rough example.
// String.prototype.replace() + JSON.parse() Strategy.
const input = "['a','b','c']" // Input.
const array = JSON.parse(input.replace(/'/g, '"')) // Array.
console.log(array) // Proof.
Although, given your update/more complex use case, eval() might be more appropriate.
// eval() Strategy.
const input = `['la maison', "l'animal"]` // Input.
const dangerousarray = eval(input) // Array.
const safearray = eval(`new Array(${input.replace(/^\[|\]$/g, '')})`)
console.log(dangerousarray) // Proof.
console.log(safearray) // Proof.
However, the MDN docs discourage use of eval() due to security/speed flaws.
As a result, one may opt for an approach similar to the following:
// Heavy Replacement Strategy.
const input = `['la maison', 'l\'animal']` // Input.
const array = input
.replace(/^\[|\]$/g, '') // Remove leading and ending square brackets ([]).
.split(',') // Split by comma.
.map((phrase) => // Iterate over each phrase.
phrase.trim() // Remove leading and ending whitespace.
.replace(/"/g, '') // Remove all double quotes (").
.replace(/^\'|\'$/g, '') // Remove leading and ending single quotes (').
)
console.log(array) // Proof.

In JavaScript you can use eval() Function like the sample bellows :
// define the string to evaluate
var str_to_evaluate = 'new Array("Saab", "Volvo", "BMW")';
// retreive the result in a array
var cars = eval(str_to_evaluate);
// print the array
console.log(cars);

Related

Javascript include delimiter when using command [.split]

Question:
Is it possible to keep the selected delimiter using javascript [.split], without involving regex? In below example I am sending in the commands using node.js.
// A css text string.
var text_string = "div-1{color:red;}div-2{color:blue;}";
// Split by [}], removes the delimiter:
var partsOfStr = text_string.split('}');
// Printouts
console.log("Original: " + text_string); // Original.
console.log(partsOfStr); // Split into array.
console.log(partsOfStr[0]); // First split.
console.log(partsOfStr[1]); // Second split.
The output:
Original: div-1{color:red;}div-2{color:blue;}
[ 'div-1{color:red;', 'div-2{color:blue;', '' ]
div-1{color:red;
div-2{color:blue;
Wanted behaviour:
I need the output to include the delimitor [ } ]. The result lines should look line this:
div-1{color:red};
div-2{color:blue};
I did find below question but it does not use javascript split, it uses regex:
Javascript split include delimiters
Here's a way using replace - although technically there is a regex involved. Techical in an almost pedantic way since it matches the actual strings, only between slashes rather than quotes.
var text_string = "div-1{color:red;}div-2{color:blue;}";
var partsOfString = text_string.replace(/;}/g, "};\n")
console.log(partsOfString);

Regular Expression to get the last word from TitleCase, camelCase

I'm trying to split a TitleCase (or camelCase) string into precisely two parts using javascript. I know I can split it into multiple parts by using the lookahead:
"StringToSplit".split(/(?=[A-Z])/);
And it will make an array ['String', 'To', 'Split']
But what I need is to break it into precisely TWO parts, to produce an array like this:
['StringTo', 'Split']
Where the second element is always the last word in the TitleCase, and the first element is everything else that precedes it.
Is this what you are looking for ?
"StringToSplit".split(/(?=[A-Z][a-z]+$)/); // ["StringTo", "Split"]
Improved based on lolol answer :
"StringToSplit".split(/(?=[A-Z][^A-Z]+$)/); // ["StringTo", "Split"]
Use it like this:
s = "StringToSplit";
last = s.replace(/^.*?([A-Z][a-z]+)(?=$)/, '$1'); // Split
first = s.replace(last, ''); // StringTo
tok = [first, last]; // ["StringTo", "Split"]
You could use
(function(){
return [this.slice(0,this.length-1).join(''), this[this.length-1]];
}).call("StringToSplit".split(/(?=[A-Z])/));
//=> ["StringTo", "Split"]
In [other] words:
create the Array using split from a String
join a slice of that Array without the last element of that
Array
add that and the last element to a final Array

parsing key/value pairs from string

I'm parsing the body text from incoming emails, looking for key/value pairs.
Example Email Body
First Name: John
Last Name:Smith
Email : john#example.com
Comments = Just a test comment that
may span multiple lines.
I tried using a RegEx ([\w\d\s]+)\s?[=|:]\s?(.+) in multiline mode. This works for most emails, but fails when there's a line break that should be part of the value. I don't know enough about RegEx to go any further.
I have another parser that goes line-by-line looking for the key/value pairs and simply folds a line into the last matched value if a key/value pair is NOT found. It's implemented in Scala.
val lines = text.split("\\r?\\n").toList
var lastLabelled: Int = -1
val linesBuffer = mutable.ListBuffer[(String, String)]()
// only parse lines until the first blank line
// null_? method is checks for empty strings and nulls
lines.takeWhile(!_.null_?).foreach(line => {
line.splitAt(delimiter) match {
case Nil if line.nonEmpty => {
val l = linesBuffer(lastLabelled)
linesBuffer(lastLabelled) = (l._1, l._2 + "\n" + line)
}
case pair :: Nil => {
lastLabelled = linesBuffer.length
linesBuffer += pair
}
case _ => // skip this line
}
})
I'm trying to use RegEx so that I can save the parser to the db and change it on a per-sender basis at runtime (implement different parsers for different senders).
Can my RegEx be modified to match values that contain newlines?
Do I need to just forget about using RegEx and use some JavaScript? I already have a JavaScript parser that lets me store the JS in the DB and essentially do everything that I want to do with the RegEx parser.
I think this should work...
((.+?)((\s*)(:|=)(\s*)))(((.|\n)(?!((.+?)(:|=))))+)
...as tested here http://regexpal.com/. If you loop through the matches you should be able to pull out the key and value.

Regex one-liner for splitting string at nth character where n is a variable length

I've found a few similar questions, but none of them are clean one-liners, which I feel should be possible. I want to split a string at the last instance of specific character (in my case .).
var img = $('body').attr('data-bg-img-url'); // the string http://sub.foo.com/img/my-img.jpg
var finalChar = img.split( img.split(/[.]+/).length-1 ); // returns int 3 in above string example
var dynamicRegex = '/[.$`finalChar`]/';
I know I'm breaking some rules here, wondering if someone smarter than me knows the correct way to put that together and compress it?
EDIT - The end goal here is to split and store http://sub.foo.com/img/my-img and .jpg as separate strings.
In regex, .* is greedy, meaning it will match as much as possible. Therefore, if you want to match up to the last ., you could do:
/^.*\./
And from the looks, you are trying to get the file extension, so you would want to add capture:
var result = /^.*\.(.*)$/.exec( str );
var extension = result[1];
And for both parts:
var result = /^(.*)\.(.*)$/.exec( str );
var path = result[1];
var extension = result[2];
You can use the lastIndexOf() method on the period and then use the substring method to obtain the first and second string. The split() method is better used in a foreach scenario where you want to split at all instances. Substring is preferable for these types of cases where you are breaking at a single instance of the string.

Splitting string in javascript

How can I split the following string?
var str = "test":"abc","test1":"hello,hi","test2":"hello,hi,there";
If I use str.split(",") then I won't be able to get strings which contain commas.
Whats the best way to split the above string?
I assume it's actually:
var str = '"test":"abc","test1":"hello,hi","test2":"hello,hi,there"';
because otherwise it wouldn't even be valid JavaScript.
If I had a string like this I would parse it as an incomplete JSON which it seems to be:
var obj = JSON.parse('{'+str+'}');
and then use is as a plain object:
alert(obj.test1); // says: hello,hi
See DEMO
Update 1: Looking at other answers I wonder whether it's only me who sees it as invalid JavaScript?
Update 2: Also, is it only me who sees it as a JSON without curly braces?
Though not clear with your input. Here is what I can suggest.
str.split('","');
and then append the double quotes to each string
str.split('","'); Difficult to say given the formatting
if Zed is right though you can do this (assuming the opening and closing {)
str = eval(str);
var test = str.test; // Returns abc
var test1 = str.test1; // returns hello,hi
//etc
That's a general problem in all languages: if the items you need contain the delimiter, it gets complicated.
The simplest way would be to make sure the delimiter is unique. If you can't do that, you will probably have to iterate over the quoted Strings manually, something like this:
var arr = [];
var result = text.match(/"([^"]*"/g);
for (i in result) {
arr.push(i);
}
Iterate once over the string and replace commas(,) following a (") and followed by a (") with a (%) or something not likely to find in your little strings. Then split by (%) or whatever you chose.

Categories

Resources