The code below gives a final undefined part...trying to figure where the undefined part is created. Any thoughts?
jQuery(document).ready(function() {
console.log("ok");
var object = {};
var text = `#DATA1 1000
#DATA2 1000
#DATA3 2000
#DIM 1 "test"
#DIM 6 "test2"`;
var lines = text.split('\n');
for (var line = 0; line < lines.length; line ) {
//console.log(lines[line]);
if (lines[line].startsWith("#DIM")) {
//console.log(lines[line]);
var myRegexp = /[^\s"] |"([^"]*)"/gi;
var row = [];
do {
//Each call to exec returns the next regex match as an array
var match = myRegexp.exec(lines[line]);
if (match != null) {
//console.log(match);
row.push(match[1] ? match[1] : match[0]);
object[row[1]] = {
namn: row[2]
};
}
//console.log(row);
} while (match != null);
}
}
console.log(object);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
The problem is that on your first pass, row has only one element in it (row[0]), so row[1] and row[2] are both undefined.
I think the goal of this code is to build an object with properties derived from the #DIM 1 "test" and #DIM 6 "test"2 lines, giving the properties the names "1", "2", etc. with the values of the text in quotes. If so, you don't need row at all, see comments:
const text = `#DATA1 1000
#DATA2 1000
#DATA3 2000
#DIM 1 "test"
#DIM 6 "test2"`;
const object = {};
// Use multiline flag so `^` matches start-of-line and
// $ matches end-of-line
const rexParseLine = /^#DIM\s (\S )\s "([^"] )"\s*$/gm;
let match;
while ((match = rexParseLine.exec(text)) !== null) {
object[match[1]] = match[2];
}
console.log(object);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Note that I didn't split the text into lines first, the regular expression can handle working within lines if we use the multiline (m) flag. Here'sa breakdown of the regex:
^#DIM- line starts with#DIM\s- followed by one or more whitespace chars(\S )- followed by one or more non-whitespace chars that we capture\s- followed by one or more whitespace chars"([^"] )"- followed by"s with text in-between that we capture\s*$- followed by optional whitespace and end-of-line
The g flag lets use use it in a loop to work through the text, and the m flag, again, changes the meaning of ^ and $.
Side note: In modern environments, we can use named capture groups to make that clearer:
const text = `#DATA1 1000
#DATA2 1000
#DATA3 2000
#DIM 1 "test"
#DIM 6 "test2"`;
const object = {};
// Use multiline flag so `^` matches start-of-line and
// $ matches end-of-line
const rexParseLine = /^#DIM\s (?<key>\S )\s "(?<value>[^"] )"\s*$/gm;
let match;
while ((match = rexParseLine.exec(text)) !== null) {
const {key, value} = match.groups;
object[key] = value;
}
console.log(object);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
But I have to admit it's not clear to me why you were allowing for the first capture group to be empty, so that may need tweaking.
