Skip to content

Commit 9b7db1e

Browse files
committed
Rewrite parseINI function again
1 parent 8f68dd4 commit 9b7db1e

File tree

1 file changed

+34
-28
lines changed

1 file changed

+34
-28
lines changed

09_regexp.md

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,42 +1061,40 @@ between lines.
10611061
```
10621062
function parseINI(string) {
10631063
// Start with an object to hold the top-level fields
1064-
return string.split(/\r?\n/).reduce((sections, line) => {
1065-
if (/^\s*(;.*)?$/.test(line)) return sections;
1066-
1064+
let result = {};
1065+
let section = result;
1066+
string.split(/\r?\n/).forEach(line => {
10671067
let match;
1068-
if (match = line.match(/^\[(.*)\]$/)) {
1069-
return [...sections, {title: match[1], fields: []}];
1070-
} else if (match = line.match(/^(\w+)=(.*)$/)) {
1071-
let [_, name, value] = match;
1072-
let {title, fields} = sections[sections.length - 1];
1073-
return [...sections.slice(1),
1074-
{title, fields: [{name, value}, ...fields]}];
1075-
} else {
1076-
throw new Error("Line '" + line + "' is invalid.");
1068+
if (match = line.match(/^(\w+)=(.*)$/)) {
1069+
section[match[1]] = match[2];
1070+
} else if (match = line.match(/^\[(.*)\]$/)) {
1071+
section = result[match[1]] = {};
1072+
} else if (!/^\s*(;.*)?$/.test(line)) {
1073+
throw new Error("Line '" + line + "' is not valid.");
10771074
}
1078-
}, [{title: null, fields: []}]);
1075+
});
1076+
return result;
10791077
}
1078+
1079+
console.log(parseINI(`
1080+
name=Vasilis
1081+
[address]
1082+
city=Tessaloniki`));
1083+
// → {name: "Vasilis", address: {city: "Tessaloniki"}}
10801084
```
10811085

10821086
{{index "parseINI function", parsing}}
10831087

1088+
The code goes over the file's lines and builds up an object.
1089+
Properties at the top are stored directly into the object, whereas
1090+
properties found in sections are stored in sub-objects stored under
1091+
the section's name. The `section` binding points at the object that
1092+
holds the current section.
10841093

1085-
The code reduces the file's lines to an array of sections, starting
1086-
with a single, untitled section.
1087-
1088-
When it finds an empty line or a comment, it ignores it. The
1089-
expression `/^\s*(;.*)?$/` recognizes such lines. Do you see how it
1090-
works? The part between the ((parentheses)) will match comments, and
1091-
the `?` makes sure it also matches lines containing only whitespace.
1092-
1093-
If the line is not a ((comment)), it may be a section header or a
1094-
regular option line. When it is a new section, an appropriate section
1095-
object is added to the array. When it is an option, an object
1096-
representing that option is added to the current (last) section.
1097-
1098-
If a ((line)) matches none of these forms, the function throws an
1099-
error.
1094+
There are two kinds of significant lines—section headers or property
1095+
lines. When a line is a regular property, it is stored in the current
1096+
section. When it is a section header, a new section object is created,
1097+
and `section` is set to point at it.
11001098

11011099
{{index "caret character", "dollar sign", boundary}}
11021100

@@ -1115,6 +1113,13 @@ not break the pleasant chain of `if` forms, we assign the result of
11151113
the match to a binding and immediately use that assignment as the test
11161114
in the `if` statement.
11171115

1116+
If a line is not a section header or a property, the function checks
1117+
whether it is a comment or an emty line using the expression
1118+
`/^\s*(;.*)?$/`. Do you see how it works? The part between the
1119+
((parentheses)) will match comments, and the `?` makes sure it also
1120+
matches lines containing only whitespace. When a line doesn't match
1121+
any of the expected forms, the function throws an exception.
1122+
11181123
## International characters
11191124

11201125
{{index internationalization, Unicode, ["regular expression", internationalization]}}
@@ -1313,6 +1318,7 @@ function verify(regexp, yes, no) {
13131318
}
13141319
}
13151320
```
1321+
13161322
if}}
13171323

13181324
### Quoting style

0 commit comments

Comments
 (0)