Created
December 27, 2022 21:59
-
-
Save kipcole9/c3636d29d2b8df90caa6a7c9818275fe to your computer and use it in GitHub Desktop.
Split text at a separators using NimbleParsec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule NimbleSplit do | |
@moduledoc """ | |
Split text at a separator using [nimble_parsec](https://hex.pm/packages/nimble_parsec) | |
""" | |
import NimbleParsec | |
def test_string do | |
""" | |
some text, may also contain character "=", which is part of the separator | |
can be any number of lines long until the first separator line | |
========== | |
next block of text | |
========== | |
and another one | |
""" | |
end | |
# A separator line. Note inclusion of the | |
# surrounding newlines | |
separator = | |
string("\n==========\n") | |
# A line is just a series of characters up to | |
# but not including a newline | |
line = | |
repeat(utf8_char([{:not, ?\n}])) | |
# A block is a series of lines, stopping when the | |
# next line is a separator | |
block = | |
line | |
|> repeat(lookahead_not(separator) |> ascii_char([?\n]) |> concat(line)) | |
|> reduce({List, :to_string, []}) | |
# The last block might not be terminated by | |
# a separator | |
last_block = | |
line | |
|> repeat(ascii_char([?\n]) |> concat(line)) | |
|> reduce({List, :to_string, []}) | |
# Zero or more blocks separated by the separator | |
# with maybe a final block | |
defparsec(:parse, repeat(block |> ignore(separator)) |> concat(last_block)) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment