【发布时间】:2014-04-19 16:05:38
【问题描述】:
是否有一个函数可以检查字符串是否以某个子字符串结尾? Python有endswith:
>>> "victory".endswith("tory")
True
【问题讨论】:
标签: string emacs elisp substring string-matching
是否有一个函数可以检查字符串是否以某个子字符串结尾? Python有endswith:
>>> "victory".endswith("tory")
True
【问题讨论】:
标签: string emacs elisp substring string-matching
只需安装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 (< 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 状态机进行测试。不出所料,这要慢几个数量级。
您可以在调用string-match 函数时使用正则表达式。
(if (string-match-p "tory\\'" "victory")
(message "victory ends with tory.")
(message "victory does not ends with tory."))
【讨论】:
$ 匹配行的结尾。您必须使用\\' 来匹配字符串的结尾。
string-match-p 来保留match-data。
(string-match "\\.txt$" "foo.txtAAA") 返回 nil,这是预期的结果。请问有反例吗?
(string-match "\\.txt$" "foo.txt\nAAA")