From 3c0940082ff49695ac9c2147c900b959be5f8e70 Mon Sep 17 00:00:00 2001 From: Vijay Marupudi Date: Sat, 12 Feb 2022 22:00:57 -0500 Subject: [PATCH] Add string-split-substring * /ref/api-data.texi: Added documentation * module/ice-9/string-fun.scm: Added implementation * test-suite/tests/strings.test: Added tests --- doc/ref/api-data.texi | 10 ++++++++++ module/ice-9/string-fun.scm | 23 ++++++++++++++++++++++- test-suite/tests/strings.test | 22 +++++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 8658b9785..a5fcc47b1 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -4245,6 +4245,16 @@ Return a new string where every instance of @var{substring} in string @end lisp @end deffn +@deffn {Scheme Procedure} string-split-substring str substring +Split the string @var{str} into a list of substrings delimited by the +appearance of substring @var{substring}. For example: + +@lisp +(string-replace-substring "item-1::item-2::item-3::item-4" "::") +@result{} ("item-1" "item-2" "item-3" "item-4") +@end lisp +@end deffn + @node Representing Strings as Bytes @subsubsection Representing Strings as Bytes diff --git a/module/ice-9/string-fun.scm b/module/ice-9/string-fun.scm index 03e0238fa..a1d4c0366 100644 --- a/module/ice-9/string-fun.scm +++ b/module/ice-9/string-fun.scm @@ -26,7 +26,7 @@ separate-fields-before-char string-prefix-predicate string-prefix=? sans-surrounding-whitespace sans-trailing-whitespace sans-leading-whitespace sans-final-newline has-trailing-newline? - string-replace-substring)) + string-replace-substring string-split-substring)) ;;;; ;;; @@ -313,3 +313,24 @@ (else (display (substring/shared str start))))))))) +(define (string-split-substring str substr) + "Split the string @var{str} into a list of substrings delimited by the +substring @var{substr}." + + (define substrlen (string-length substr)) + (define strlen (string-length str)) + + (define (loop index start) + (cond + ((>= start strlen) (list "")) + ((not index) (list (substring str start))) + (else + (cons (substring str start index) + (let ((new-start (+ index substrlen))) + (loop (string-contains str substr new-start) + new-start)))))) + + (cond + ((string-contains str substr) => (lambda (idx) (loop idx 0))) + (else (list str)))) + diff --git a/test-suite/tests/strings.test b/test-suite/tests/strings.test index 7393bc8ec..8bc26e3e3 100644 --- a/test-suite/tests/strings.test +++ b/test-suite/tests/strings.test @@ -699,4 +699,24 @@ (pass-if "string-replace-substring" (string=? (string-replace-substring "a ring of strings" "ring" "rut") - "a rut of struts"))) + "a rut of struts")) + + (pass-if "string-split-substring - empty string" + (equal? (string-split-substring "" "foo") + '(""))) + + (pass-if "string-split-substring - non-empty, no delimiters" + (equal? (string-split-substring "testing" "foo") + '("testing"))) + + (pass-if "string-split-substring - non-empty, delimiters" + (equal? (string-split-substring "testingfoobar" "foo") + '("testing" "bar"))) + + (pass-if "string-split-substring - non-empty, leading delimiters" + (equal? (string-split-substring "foobar" "foo") + '("" "bar"))) + + (pass-if "string-split-substring - non-empty, trailing delimiters" + (equal? (string-split-substring "barfoo" "foo") + (list "bar" "")))) -- 2.35.1