Trim/Strip
As said in the examples, this predicate can be used to trim strings, i.e. remove leading and trailing whitespace although there should really be a proper trim_string/2 and trim_atom/2 predicates. Naming discloses intent.
- In Python, this operation is called strip
- Java has both a
stripand atrimfor theStringclass, and they slightly differ.
However, there is no predicate to do that for atoms, lists-of-chars, or lists-of-codes. Does one have to transform these into a string and back? Sounds suboptimal.
A simple trim for atoms and list-of-char could be as follows (quite inefficient due to the way append/2 generates candidates to test, but rather compact):
% trim(Chars,TrimmedChars)
trim(Atom,TrimmedAtom) :-
atom_chars(Atom,Chars),
trim_chars(Chars,TrimmedChars),
atom_chars(TrimmedAtom,TrimmedChars).
trim_chars(Chars,TrimmedChars) :-
append([Prefix,TrimmedChars,Suffix],Chars),
forall(member(X,Prefix),is_blank(X)),
forall(member(X,Suffix),is_blank(X)),
(
TrimmedChars == [];
(TrimmedChars = [First|_], \+is_blank(First), last(TrimmedChars,Last), \+is_blank(Last))
).
is_blank(X) :-
memberchk(X,[' ','\n','\r','\t']). % should be extended to the whole unicode "blank" class
See also
atomic_list_concat/3, which is similar when it is run "in reverse".
Test code
:- begin_tests(split_string).
test("Simple split") :-
split_string("a.b.c.d", ".", "", L),
assertion(L == ["a", "b", "c", "d"]).
test("Split with sep-char at the extremities") :-
split_string(".a.b.c.d.", ".", "", L),
assertion(L == ["", "a", "b", "c", "d", ""]).
test("Split with sep-char sequence") :-
split_string("a.b...c.d", ".", "", L),
assertion(L == ["a","b","","","c","d"]).
test("Split with sep-char sequence, but collapse sequences") :-
split_string("a.b...c.d", ".", ".", L),
assertion(L == ["a","b","c","d"]).
test("Split with sep-char at the extremities, but collapse sequences") :-
split_string(".a.b.c.d.", ".", ".", L),
assertion(L == ["a","b","c","d"]).
test("Split with sep-char sequence, but collapse sequences, take 2") :-
split_string("/home//jan///nice/path", "/", "/", L),
assertion(L == ["home", "jan", "nice", "path"]).
test("Split and remove white space") :-
split_string("SWI-Prolog, 7.0", ",", " ", L),
assertion(L == ["SWI-Prolog", "7.0"]).
test("Remove leading and trailing white space, i.e.'trim' (no whitespace inside string)") :-
split_string(" SWI-Prolog ", "", "\s\t\n", L),
assertion(L == ["SWI-Prolog"]).
test("Remove leading and trailing white space, i.e.'trim' (whitespace inside string)") :-
split_string(" SWI Prolog ", "", "\s\t\n", L),
assertion(L == ["SWI Prolog"]).
test("Remove leading and trailing white space, i.e.'trim' (lots of whitespace inside string)") :-
split_string(" SWI Super Prolog ", "", "\s\t\n", L),
assertion(L == ["SWI Super Prolog"]).
:- end_tests(split_string).