-
-
Save crespire/35ad962c5740aade6a7977b1a87bd250 to your computer and use it in GitHub Desktop.
Join/Split with arbitrary single-char dlimiter
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
def join(strings, delimiter) | |
raise ArgumentError, "Invalid delimiter \"\\\"" if delimiter == "\\" | |
strings.map do |s| | |
s.gsub(/(\\|#{Regexp.escape(delimiter)})/, '\\\\\1') | |
end.join(delimiter) | |
end | |
def split(string, delimiter) | |
raise ArgumentError, "Invalid delimiter \"\\\"" if delimiter == "\\" | |
strings = [] | |
token = nil | |
literal = false | |
string.chars.each do |char| | |
token ||= "" | |
if literal | |
token += char | |
literal = false | |
next | |
end | |
case char | |
when "\\" | |
literal = true | |
when delimiter | |
strings << token | |
token = "" | |
else | |
token += char | |
end | |
end | |
raise ArgumentError, "dangling escape" if literal | |
strings << token unless token.nil? | |
strings | |
end |
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
require_relative './delim' | |
# { delimiter => { string => array , ... }, ... } | |
# for each string/array pair S/A: | |
# - join(A) == S | |
# - split(S) == A | |
test_cases = { | |
":" => { | |
"" => [], | |
"foo" => ["foo"], | |
":" => ["", ""], | |
"foo:bar" => ["foo", "bar"], | |
'foo\:bar' => ["foo:bar"], | |
"foo:" => ["foo", ""], | |
"foo:bar:" => ["foo", "bar", ""], | |
':foo\::\:bar:\:::' => ["", "foo:", ":bar", ":", "", ""], | |
"\\\\:foo" => ["\\", "foo"], | |
"\\\\\\:foo" => ["\\:foo"], | |
"foo\\\\\\:\\\\bar" => ["foo\\:\\bar"] | |
}, | |
# Regex character | |
"|" => { | |
"" => [], | |
"foo" => ["foo"], | |
"|" => ["", ""], | |
"foo|bar" => ["foo", "bar"], | |
'foo\|bar' => ["foo|bar"], | |
"foo|" => ["foo", ""], | |
"foo|bar|" => ["foo", "bar", ""], | |
'|foo\||\|bar|\|||' => ["", "foo|", "|bar", "|", "", ""], | |
"\\\\|foo" => ["\\", "foo"], | |
"\\\\\\|foo" => ["\\|foo"], | |
"foo\\\\\\|\\\\bar" => ["foo\\|\\bar"] | |
}, | |
" " => { | |
"" => [], | |
"foo" => ["foo"], | |
" " => ["", "", "", ""], | |
' \ ' => ["", " ", ""], | |
"this is a test" => ["this", "is", "a", "test"], | |
%q[\ this\ is a\ test\ ] => [" this is", "a test "] | |
}, | |
"\n" => { | |
"" => [], | |
"\n" => ["", ""], | |
"foo\nbar" => ["foo", "bar"], | |
"foo\\\nbar" => ["foo\nbar"], | |
"\nfoo\\\nbar\n" => ["", "foo\nbar", ""] | |
} | |
} | |
test_cases.each do |delimiter, cases| | |
cases.each do |str, arr| | |
got = split(str, delimiter) | |
if got != arr | |
puts "split(#{str.inspect}, #{delimiter.inspect}): Got #{got.inspect}, want #{arr.inspect}" | |
end | |
end | |
cases.each do |str, arr| | |
got = join(arr, delimiter) | |
if got != str | |
puts "join(#{arr.inspect}, #{delimiter.inspect}): Got #{got.inspect}, want #{str.inspect}" | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment