2010-10-09 4 views
2

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

ответ

3

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

;; 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. Если вы хотите использовать match-data послесловия, удалите вызов 'save-match-data.

+1

'(buffer-string)' делает копию содержимого буфера, поэтому для больших буферов это нецелесообразно. – Gilles

+0

@ Gilles - очень верно, я добавлю примечание, указывающее, что я должен был первоначально. Благодарю. –

+0

Я пришел к решению так же, как и ваш код в конце. Благодарю. –

5

функция, соответствующая 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))) 
     ...)))