strpos в Emacs Lisp

Есть ли встроенная функция Emacs Lisp, которая ведет себя как strpos() в PHP? Он должен вернуть позицию первого появления данной строки в текущем буфере. функция search-forward это хорошо, но это изменяет положение персонажа.

2 ответа

Решение

Ты можешь сделать:

;; does not modify match-data
(string-match-p (regexp-quote "string") (buffer-string))

или же

;; does modify match-data
(string-match (regexp-quote "string") (buffer-string))

Но эти вызовы делают копию строки, что непрактично. Лучшее решение было бы использовать это:

(defun my-strpos (string)
  "mimic strpos"
  (save-excursion
    (save-match-data
      (goto-char (point-min))               ; or not
      (when (search-forward string nil t)
        (match-beginning 0)))))

Это также зависит от того, что вы хотите сделать после нахождения позиции. Документация по данным совпадений может быть полезной. Если вы хотите использовать match-data послесловия, убрать звонок 'save-match-data,

Функция, соответствующая strpos в PHP, чтобы найти строку внутри другой строки, search от cl пакет:

(require 'cl)
(search needle haystack :start2 offset)

Если вы хотите найти строку внутри буфера, используйте search-forward, Так как это изменяет текущий буфер и точку внутри этого буфера, вам нужно обернуть вашу функцию внутри save-excursion; это распространенная идиома Emacs Lisp. Вы должны также обернуть свою функцию в save-match-data, чтобы не мешать поискам того, что вызывает ваш код.

(save-match-data
  (save-excursion
    (set-buffer haystack)
    (goto-char (or offset (point-min)))
    (let ((pos (search-forward needle nil t)))
      ...)))
Другие вопросы по тегам