schemedoc / cookbook

New Scheme Cookbook
https://cookbook.scheme.org
30 stars 3 forks source link

[Recipe] Searching sub string inside a string #29

Closed jcubic closed 3 years ago

jcubic commented 3 years ago

Problem

You want to search and find the index of a string inside a bigger string.

Solution

(define (string-find haystack needle . rest)
  (let ((start (if (null? rest) 0 (car rest))))
    (let* ((haystack-len (string-length haystack))
           (needle-len (string-length needle))
           (start 0))
      (let loop ((h-index start)
                 (n-index 0))
        (let ((h-char (string-ref haystack h-index))
              (n-char (string-ref needle n-index)))
          (if (char=? h-char n-char)
              (if (= (+ n-index 1) needle-len)
                  (+ (- h-index needle-len) 1)
                  (loop (+ h-index 1) (+ n-index 1)))
              (if (= (+ h-index 1) haystack-len)
                  #f
                  (loop (+ h-index 1) 0))))))))

SRFI

The same functionality is provided by SRFI-13 function string-contains and string-contains-ci

Credit: @jcubic

Usage

(let* ((input "This is hello world")
       (search "hello")
       (found (string-find input search)))
  (if found
      (begin
        (display (substring input found))
        (newline))))
;; ==> "helo world"
jcubic commented 3 years ago

I was searching SRFI-13 but it seems that search string is missing there is only searching for character

jcubic commented 3 years ago

I'm also not sure if string->vector is needed, I was trying to use string-index from SRFI, but it was way too complex.

lassik commented 3 years ago

string-contains and string-contains-ci do it, they return the index where the substring appears. The names of these procedures are a bit confusing.