检查字符串是不是以 Emacs Lisp 中的后缀结尾

Posted

技术标签:

【中文标题】检查字符串是不是以 Emacs Lisp 中的后缀结尾【英文标题】:Check if a string ends with a suffix in Emacs Lisp检查字符串是否以 Emacs Lisp 中的后缀结尾 【发布时间】:2014-04-19 16:05:38 【问题描述】:

是否有一个函数可以检查字符串是否以某个子字符串结尾? Python有endswith:

>>> "victory".endswith("tory")
True

【问题讨论】:

【参考方案1】:

只需安装s.el 字符串操作库并使用它的s-suffix? 谓词:

(s-suffix? "turn." "...when it ain't your turn.") ; => t

但是如果你拒绝使用这个库,你必须编写自己的函数。在subr.el 中有string-prefix-p,它类似于Python 的str.startswith,它只是compare-strings 的包装。根据Emacs 24.3 changelog:

** New function `string-prefix-p'.
(This was actually added in Emacs 23.2 but was not advertised at the time.)

string-suffix-p 是 added only in Emacs 24.4,所以对于早期版本,我写道:

(defun string-suffix-p (str1 str2 &optional ignore-case)
  (let ((begin2 (- (length str2) (length str1)))
        (end2 (length str2)))
    (when (< begin2 0) (setq begin2 0))
    (eq t (compare-strings str1 nil nil
                           str2 begin2 end2
                           ignore-case))))

(when (&lt; begin2 0) (setq begin2 0)) 是一种解决方法,因为如果您将负数传递给compare-strings,它会与*** Eval error *** Wrong type argument: wholenump, -1 发生冲突。

如果你对函数进行字节编译,它比yves Baumes 解决方案运行得更快,即使string-match 是一个C 函数。

ELISP> (setq str1 "miss."
             str2 "Ayo, lesson here, Bey. You come at the king, you best not miss.")
ELISP> (benchmark-run 1000000 (string-suffix-p str1 str2))
(4.697675135000001 31 2.789847821000066)
ELISP> (byte-compile 'string-suffix-p)
ELISP> (benchmark-run 1000000 (string-suffix-p str1 str2))
(0.43636462600000003 0 0.0)
ELISP> (benchmark-run 1000000 (string-match "miss\.$" str2))
(1.3447664240000001 0 0.0)

【讨论】:

compare-strings 也是在 C 中实现的,很可能是一个简单的逐字节内存比较,而 string-match 需要编译并运行 RE 状态机进行测试。不出所料,这要慢几个数量级。【参考方案2】:

您可以在调用string-match 函数时使用正则表达式。

(if (string-match-p "tory\\'" "victory")
    (message "victory ends with tory.")
   (message "victory does not ends with tory."))

【讨论】:

你没有转义点,所以在这个版本中它匹配 txt 之前的任何字符,而不仅仅是一个点(例如它也匹配 footxt -1: $ 匹配的结尾。您必须使用\\' 来匹配字符串的结尾。 另外,您应该使用string-match-p 来保留match-data @lunaryorn 同样(string-match "\\.txt$" "foo.txtAAA") 返回 nil,这是预期的结果。请问有反例吗? @yvesBaumes (string-match "\\.txt$" "foo.txt\nAAA")

以上是关于检查字符串是不是以 Emacs Lisp 中的后缀结尾的主要内容,如果未能解决你的问题,请参考以下文章

我是怎样使用 Emacs 的

Emacs Lisp:获取字符的 ascii 值

在 emacs lisp 中将多个路径组件加入到单个完整路径中的正确方法是啥?

以编程方式使用前缀参数的emacs lisp调用函数

Common Lisp 入门配置开发环境 in Emacs

Emacs我想从lisp函数调用execute-kbd-macro