Home   Archive   Permalink



Parsing on a non-printable character

More parsing difficulties.
    
In SQL Server, one can copy to the clipboard the results of a query, and those results seem to be lines delimited by the carriage-return-line-feed characters (0D0A), but they are in the clipboard as one big string. So I want to divide them up on the CR-LF into a block of lines so I can do stuff with them. I seem to be unable to format that parse function call correctly and wonder if anyone can straighten me out. Here is what I have tried so far without success: Thank you.
    
R E B O L [
     Title: "Clipboard lines"
     Purpose: {Read from the clipboard a string of lines delimited by
     cr-lf, and return a block of those lines suitable for examination
     on a line-by-line basis.}
]
    
CLIPBOARD-LINES: func [
     /local CLIPSTRING LINEBLOCK
] [
     LINEBLOCK: copy []
     CLIPSTRING: copy ""
     CLIPSTRING: read clipboard://
;;;;LINEBLOCK: parse/all CLIPSTRING #"(0D0A)"
;;;;LINEBLOCK: parse/all CLIPSTRING #(0D0A)
;;;;LINEBLOCK: parse/all CLIPSTRING to-string #"(0D0A)"
;;;;LINEBLOCK: parse/all CLIPSTRING to-string #(0D0A)
;;;;LINEBLOCK: parse/all CLIPSTRING newline
;;; LINEBLOCK: parse/all CLIPSTRING rejoin [#(0D) #(0A)]
     return LINEBLOCK
]
    
;;Uncomment to test
CLIPPEDLINES: CLIPBOARD-LINES
print [length? CLIPBEDLINES " lines"]
halt


posted by:   Steven White     15-Oct-2018/11:41:05-7:00



CR-LF is two characters, so you'll need a string to match it:
    
"^(0D)^(0A)"
"^M^/"
to string! #{0D0A}
crlf

posted by:   Chris     15-Oct-2018/13:31:10-7:00



Here's an example of breaking up those lines:
    
collect [
     use [mark][
         while [mark: find clipstring crlf][
             keep copy/part clipstring mark
             clipstring: next next mark
         ]
         unless empty? clipstring [keep clipstring]
     ]
]
    
Note that this will modify CLIPSTRING.

posted by:   Chris     16-Oct-2018/10:30:13-7:00



Hm, not modify, but will not be guaranteed to point to the head of the string.
    
Shouldn't be too hard to adapt a parse rule to replace this loop:
    
collect [
     use [mark][
         parse/all clipstring [
             any [
                 clipstring: to crlf mark: 2 skip
                 (keep copy/part clipstring mark)
             ]
             [end | to end (keep copy clipstring)]
         ]
     ]
]

posted by:   Chris     16-Oct-2018/10:35:11-7:00



Thank you. I just did this, and it seemed to work just fine.    
    
I keep forgetting about that collect/keep.
    
CLIPBOARD-LINES: func [
     /local CLIPSTRING LINEBLOCK
] [
     LINEBLOCK: copy []
     CLIPSTRING: copy ""
     CLIPSTRING: read clipboard://
     LINEBLOCK: parse/all CLIPSTRING "^(0D)^(0A)"
     return LINEBLOCK
]

posted by:   Steven White     16-Oct-2018/12:16:37-7:00