Search code examples
red-lang

In Red language, how to split a string using split, but also keep the delimiters as nessecary


I want to split a string with the split, meanwhile the string contains the string used as delimiter which should not be treated as delimiter. I tried in this way as shown in the following code:

>> split {1 + 3 `to-string #"^(60)"`c} "`"
== ["1 + 3 " {to-string #"} {"} "c"] ;;I think it should be ["1 + 3 " {to-string #"^(60)"}"c"] 

to-string #"^(60)" used here is to avoid the appearance of "``" which would be referred as delimiter, but it fails. It seems that the ^(60) is evaluated to "```" and then is used as delimiter by split. So, what is the mechanism of the split in Red language? And how to split a string meanwhile keeping those delimiters that should not be treated as delimiter.


Solution

  • ^(60) is a so-called codepoint form that gets loaded as a ` character.

    >> "^(60)"
    == "`"
    

    If you want to avoid that, you should either escape it manually:

    >> {1 + 3 `to-string #"^^(60)"` c}
    == {1 + 3 `to-string #"^^(60)"` c}
    

    Or use raw strings:

    >> %{1 + 3 `to-string #"^(60)"` c}%
    == {1 + 3 `to-string #"^^(60)"` c}
    

    splitting it afterwards is trivial:

    >> split %{1 + 3 `to-string #"^(60)"` c}% #"`"
    == ["1 + 3 " {to-string #"^^(60)"} " c"]
    

    In case you want to keep ` character there, then split won't cut it. You need something like Parse:

    >> string: {1 + 3 `to-string #"`"` c}
    == {1 + 3 `to-string #"`"` c}
    >> parse string [collect [keep to " `" " `" keep to "` " "` " keep copy match to end]]
    == ["1 + 3" {to-string #"`"} "c"]
    >> parse string [collect some [keep copy _ to copy match [" `" | "` " | end] match]]
    == ["1 + 3" {to-string #"`"} "c"]