6

全部。我想知道 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         
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 字符的假设),但我想知道我是否遗漏了一些我应该知道的明显功能。

4

4 回答 4

13

参考其他答案:

  1. 使用upcase不是一个好主意:它会分配一个新字符串,它不会找到字符串是否有非字母字符(似乎你想禁止它),它也适用于整数(Emacs 用于字符) .

  2. 使用string-match更好——它解决了所有这些问题。正如 Trey 所示,您需要这样做,case-fold-search否则nilEmacs 可能会将其视为不区分大小写的搜索。但是string-match-p更好,因为它避免了更改匹配数据。(Emacs 会在任何匹配后保留该数据,如果您使用,string-match那么您将覆盖它,这可能会破坏使用您的函数的代码。)

  3. 另一个问题是正则表达式本身。Using"^...$"意味着 Emacs 将寻找具有匹配内容的某些行——如果你的字符串有换行符,这可能使它返回一个虚假的结果。您需要使用仅匹配字符串开头和结尾的反斜杠取消引用和反斜杠引用。

所以正确的版本是:

(defun string-is-capitalized (str)
  (let ((case-fold-search nil))
    (string-match-p "\\`[A-Z]*\\'" str)))

(顺便说一句,Emacs Lisp 中通常的约定是使用 a-p表示谓词,如string-capitalized-p.)

于 2010-01-25T02:55:39.347 回答
7

我不知道有一个内置函数可以满足您的需求,但这确实:

(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))))

编辑:根据Eli Barzilay的反馈更改为使用 ` 和 ' 。

这个允许有非 AZ 字符(不是你要求的,但也许很有趣):

(defun string-has-no-lowercase (string)
  "Return true iff STRING has no lowercase"
  (equal (upcase string) string))
于 2010-01-25T02:18:45.977 回答
5

外部字符串操作库s.els-uppercase?

(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))))

[[:lower:]]是对应于小写字符的Emacs 特定正则表达式。string-match-p接受一个正则表达式并返回一个索引,从该索引开始匹配正则表达式,或者nil如果没有匹配则返回。这个想法是在字符串中搜索小写字符,如果没有找到,则返回t。但是string-match-p默认情况下会忽略大小写,因此您应该暂时关闭case-fold-search.

Emacs 默认使用动态绑定,因此您可以在let表达式中临时将全局变量设置为不同的值。如果您将绑定设置为词法,那么 let 将引入 的本地副本case-fold-search,从而隐藏全局变量,因此上述代码将不起作用。

于 2015-01-06T09:20:42.410 回答
0

只是一个疯狂的猜测,但是如果你制作一个字符串的副本,将它大写(我对 lisp 不太了解,但快速谷歌搜索告诉有一个“大写”功能,然后检查两个字符串是否相同? 如果是,那么原始的必须全部大写 :P

于 2010-01-25T02:21:57.560 回答