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.