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
strip
and atrim
for theString
class, 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).