在Emacs lisp中检查字符串是否全部为大写?
全部。我想知道Emacs lisp是否有一个内置函数,用于检查字符串是否完全由大写字符组成。以下是我现在正在使用的:在Emacs lisp中检查字符串是否全部为大写?,emacs,lisp,elisp,capitalization,Emacs,Lisp,Elisp,Capitalization,全部。我想知道Emacs lisp是否有一个内置函数,用于检查字符串是否完全由大写字符组成。以下是我现在正在使用的: (setq capital-letters (string-to-list "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) (defun chars-are-capitalized (list-of-characters) "Returns true if every character in a list of characters is a capital
(setq capital-letters (string-to-list "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
(defun chars-are-capitalized (list-of-characters)
"Returns true if every character in a list of characters is a capital
letter. As a special case, the empty list returns true."
(cond
((equal list-of-characters nil) t)
((not (member (car list-of-characters) capital-letters)) nil)
(t (chars-are-capitalized (cdr list-of-characters)))))
(defun string-is-capitalized (string)
"Returns true if every character in a string is a capital letter. The
empty string returns true."
(chars-are-capitalized (string-to-list string)))
它工作正常(尽管它依赖于我将只使用ASCII字符的假设),但我想知道我是否遗漏了一些我应该知道的明显的函数。我不知道有什么内置函数可以满足您的需要,但这是:
(defun string-all-caps-p (string)
"Return non-nil iff STRING is all capital letters."
(save-match-data
(let ((case-fold-search nil))
(string-match "\\`[A-Z]+\\'" string))))
编辑:根据的反馈更改为使用“和”
这一个允许使用非A-Z字符(不是您要求的,但可能很有趣):
这只是一个粗略的猜测,但是如果你复制一个字符串,将其大写(我对lisp不太了解,但是快速的谷歌搜索告诉你有一个“大写”函数,然后检查这两个字符串是否相同?如果是,那么原始字符串必须全部大写:p,参考其他答案:
upcase
不是一个好主意:它将分配一个新字符串,它不会发现该字符串是否包含非字母字符(似乎您想禁止这样做),并且它也适用于整数(Emacs将其用于字符)string-match
更好——它解决了所有这些问题。正如Trey所示,当case-fold-search
为nil
时,您需要这样做,否则Emacs可能会将其视为不区分大小写的搜索。但是string-match-p
更好,因为它避免了更改匹配数据。(Emacs会在任何匹配后保留该数据,如果使用字符串匹配
,则会覆盖该数据,这可能会破坏使用函数的代码。)“^…$”
意味着Emacs将查找具有匹配内容的某行——如果字符串具有换行符,这可能会使其返回虚假结果。您需要使用反斜杠unquote和反斜杠quote,它们只匹配字符串的开头和结尾(defun string-is-capitalized (str)
(let ((case-fold-search nil))
(string-match-p "\\`[A-Z]*\\'" str)))
(顺便说一句,Emacs Lisp中的通常惯例是对谓词使用
-p
,如字符串大写-p
)外部字符串操作库具有:
它是这样实现的:
(defun s-uppercase? (s)
(let ((case-fold-search nil))
(not (string-match-p "[[:lower:]]" s))))
[:lower:]
是对应于小写字符的。接受正则表达式并返回一个索引,从该正则表达式开始匹配,或者如果不匹配,则返回nil
。其思想是在字符串中搜索小写字符,如果未找到,则返回t
。但是string-match-p
忽略大小写t、 因此,您应该暂时关闭
Emacs默认使用,因此您可以在
let
表达式中临时将全局变量设置为不同的值。如果您将绑定设置为词法,let将引入case fold search
的本地副本,隐藏全局变量,因此上面的代码将无法工作。第一个是有意义的;我应该认为我已经考虑过检查(相等字符串(upcase字符串)),但如果字符串中有任何非字母,我确实需要它返回false。对于第一个,您可能希望将其包装在save match data
调用中,这样任何现有的正则表达式匹配数据都不会被覆盖。而不是a-Z
我认为您希望在正则表达式中使用[:upper://code>。嗯,(1)我不喜欢[:upper:
因为它往往意味着不同的东西(有些是unicode大写字符,有些是A-Z),所以我尽可能喜欢更明确的形式;(2)我回答了最初提出的问题,代码仅限于A-Z
;(3)regexp的使用已经足够好了,所以随机旁路器在需要时自然会使用其他东西;(4)最后,请注意,我使用了“正确的版本”并避免了对regexp的讨论,以使其更加集中…这为我澄清了一个主要的困惑点,谢谢。一个次要的评论:在我的系统中,此函数可以工作,而不管函数的范围是词汇范围还是动态范围。我想知道case fold search
是否是一个所谓的特殊变量,这意味着它将要动态绑定的tinue。(有关详细信息,请参阅。)
(s-uppercase "GOT TO. THIS AMERICA, MAN.") ; t
(s-uppercase "You cannot lose if you do not play.") ; nil
(defun s-uppercase? (s)
(let ((case-fold-search nil))
(not (string-match-p "[[:lower:]]" s))))