Here’s another approach that avoids regular expressions. I still don’t have a good way to track the nesting of sub-stanzas but this does break out the top-level stanzas.
First find the positions where we need to start & end a stanza - the first position of the string, the last position of the string, and the positions in between that are the start of a new stanza (the previous character is a “%0a” and the current character is not a space):
q: concatenation "%0a" of lines of file "c:\temp\mongo.txt"
A: tls:%0a mode: requireTLS%0a certificateKeyFile: "/u01/mongo/etc/ssl/hostname.va.gov.pem"%0a CAFile: "/u01/mongo/etc/ssl/vapkirootssub1.pem"%0a FIPSMode: true%0a%0astorage:%0a dbPath: "/u01/mongo/data"%0a journal:%0a enabled: true%0asecurity:%0a keyfile: "/u01/mongo/keys/keyfile"%0a authorization: enabled%0a javascriptEnabled: false
T: 16.739 ms
q: (((starts of ( characters (positions of it) whose (start of it = 0 or (it does not start with "%0a" and it does not start with " " and last 1 of preceding text of it="%0a" )) of it); length of it)) of it) of concatenation "%0a" of lines of file "c:\temp\mongo.txt"
A: 0
A: 159
A: 229
A: 330
T: 16.374 ms
We need to put those position integers into a ‘set’ so we can compare them to each other. We want to build a list of (start position, last position) for each stanza. Loop through each number (to be a potential stanza start) and find the next-smallest number among them to be the end of the stanza:
q: (item 0 of it, item 1 of it) of ((elements of it, elements of it, it) whose (item 1 of it = minimum of items 1 of (item 0 of it, elements of item 2 of it) whose (item 1 of it > item 0 of it) ) of (set of (starts of ( characters (positions of it) whose (start of it = 0 or (it does not start with "%0a" and it does not start with " " and last 1 of preceding text of it="%0a" )) of it); length of it)) of it) of concatenation "%0a" of lines of file "c:\temp\mongo.txt"
A: 0, 159
A: 159, 229
A: 229, 330
T: 28.092 ms
We can use the substring (<start>, <length>) of <string>
inspector to retrieve the substrings between those positions , where we consider the start as ‘item 0 of it’ and the length to be ‘item 1 of it - item 0 of it’.
q: substrings ((item 0 of it, item 1 of it - item 0 of it) of ((elements of it, elements of it, it) whose (item 1 of it = minimum of items 1 of (item 0 of it, elements of item 2 of it) whose (item 1 of it > item 0 of it) ) of (set of (starts of ( characters (positions of it) whose (start of it = 0 or (it does not start with "%0a" and it does not start with " " and last 1 of preceding text of it="%0a" )) of it); length of it)) of it)) of concatenation "%0a" of lines of file "c:\temp\mongo.txt"
A: tls:%0a mode: requireTLS%0a certificateKeyFile: "/u01/mongo/etc/ssl/hostname.va.gov.pem"%0a CAFile: "/u01/mongo/etc/ssl/vapkirootssub1.pem"%0a FIPSMode: true%0a%0a
A: storage:%0a dbPath: "/u01/mongo/data"%0a journal:%0a enabled: true%0a
A: security:%0a keyfile: "/u01/mongo/keys/keyfile"%0a authorization: enabled%0a javascriptEnabled: false
Because I find ‘tuple strings’ to be easier to use in terms of looking up values in the string, I’ll split each of these results on the ‘%0a’ character and turn each into a tuple string result:
q: (tuple string of ((substrings separated by "%0a" of it) )) of substrings ((item 0 of it, item 1 of it - item 0 of it) of ((elements of it, elements of it, it) whose (item 1 of it = minimum of items 1 of (item 0 of it, elements of item 2 of it) whose (item 1 of it > item 0 of it) ) of (set of (starts of ( characters (positions of it) whose (start of it = 0 or (it does not start with "%0a" and it does not start with " " and last 1 of preceding text of it="%0a" )) of it); length of it)) of it)) of concatenation "%0a" of lines of file "c:\temp\mongo.txt"
A: tls:, mode: requireTLS, certificateKeyFile: "/u01/mongo/etc/ssl/hostname.va.gov.pem", CAFile: "/u01/mongo/etc/ssl/vapkirootssub1.pem", FIPSMode: true, ,
A: storage:, dbPath: "/u01/mongo/data", journal:, enabled: true,
A: security:, keyfile: "/u01/mongo/keys/keyfile", authorization: enabled, javascriptEnabled: false
T: 10.679 ms
That ends up with some empty values (where there was a blank line in the file), and also each item might be preceded by spaces (where there was indentation on the value in the file). We can remove those by trimming the substrings and removing the empty ones
q: (tuple string of ((substrings separated by "%0a" of it as trimmed string) whose (it != ""))) of substrings ((item 0 of it, item 1 of it - item 0 of it) of ((elements of it, elements of it, it) whose (item 1 of it = minimum of items 1 of (item 0 of it, elements of item 2 of it) whose (item 1 of it > item 0 of it) ) of (set of (starts of ( characters (positions of it) whose (start of it = 0 or (it does not start with "%0a" and it does not start with " " and last 1 of preceding text of it="%0a" )) of it); length of it)) of it)) of concatenation "%0a" of lines of file "c:\temp\mongo.txt"
A: tls:, mode: requireTLS, certificateKeyFile: "/u01/mongo/etc/ssl/hostname.va.gov.pem", CAFile: "/u01/mongo/etc/ssl/vapkirootssub1.pem", FIPSMode: true
A: storage:, dbPath: "/u01/mongo/data", journal:, enabled: true
A: security:, keyfile: "/u01/mongo/keys/keyfile", authorization: enabled, javascriptEnabled: false
Now that we have each stanza as its own result, and each result is represented in a tuple string, we can retrieve any specific value from any top-level stanza:
// retrieve 'CAFile:' from 'tls:'
q: tuple string items whose (it starts with "CAFile:") of it whose (tuple string item 0 of it starts with "tls:") of (tuple string of ((substrings separated by "%0a" of it as trimmed string) whose (it != ""))) of substrings ((item 0 of it, item 1 of it - item 0 of it) of ((elements of it, elements of it, it) whose (item 1 of it = minimum of items 1 of (item 0 of it, elements of item 2 of it) whose (item 1 of it > item 0 of it) ) of (set of (starts of ( characters (positions of it) whose (start of it = 0 or (it does not start with "%0a" and it does not start with " " and last 1 of preceding text of it="%0a" )) of it); length of it)) of it)) of concatenation "%0a" of lines of file "c:\temp\mongo.txt"
A: CAFile: "/u01/mongo/etc/ssl/vapkirootssub1.pem"
T: 8.788 ms
// retrieve 'keyfile:' from 'security:'
q: tuple string items whose (it starts with "keyfile:") of it whose (tuple string item 0 of it starts with "security:") of (tuple string of ((substrings separated by "%0a" of it as trimmed string) whose (it != ""))) of substrings ((item 0 of it, item 1 of it - item 0 of it) of ((elements of it, elements of it, it) whose (item 1 of it = minimum of items 1 of (item 0 of it, elements of item 2 of it) whose (item 1 of it > item 0 of it) ) of (set of (starts of ( characters (positions of it) whose (start of it = 0 or (it does not start with "%0a" and it does not start with " " and last 1 of preceding text of it="%0a" )) of it); length of it)) of it)) of concatenation "%0a" of lines of file "c:\temp\mongo.txt"
A: keyfile: "/u01/mongo/keys/keyfile"
T: 5.259 ms