检查字符串是否为Emacs lisp中的全部大写字母?

时间:2010-01-25 02:13:32

标签: 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         
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 个答案:

答案 0 :(得分:12)

参考其他答案:

  1. 使用upcase一个好主意:它将分配一个新字符串,如果该字符串具有非字母字符,它将无法找到(似乎您想要禁止那个),它也适用于整数(Emacs用于字符)。

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

  3. 另一个问题是regexp本身。使用"^...$"意味着Emacs将查找具有匹配内容的某些行 - 如果您的字符串具有换行符,则可能使其返回虚假结果。你需要使用反斜杠 - unquote和反斜杠引用,它们只匹配字符串的开头和结尾。

  4. 所以正确的版本是:

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

    (顺便说一下,Emacs Lisp中的通常惯例是使用-p作为谓词,如string-capitalized-p中所述。)

答案 1 :(得分: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的反馈更改为使用`和'。

这个让非A-Z字符(不​​是你要求的,但也许有趣):

(defun string-has-no-lowercase (string)
  "Return true iff STRING has no lowercase"
  (equal (upcase string) string))

答案 2 :(得分:4)

外部字符串操作库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-specific regexstring-match-p接受正则表达式并返回正则表达式匹配的索引,如果没有匹配则返回nil。我们的想法是在字符串中搜索小写字符,如果没有找到,则返回t。但是string-match-p默认情况下会忽略大小写,因此您应该暂时关闭case-fold-search

默认情况下,Emacs使用dynamic binding,因此您可以临时将全局变量设置为let表达式中的不同值。如果你设置绑定到lexical,我们会引入case-fold-search的本地副本,遮蔽全局变量,因此上面的代码不起作用。

答案 3 :(得分:0)

只是一个疯狂的猜测,但是如果你制作一个字符串的副本,就可以了解它(我真的不太了解lisp但是快速谷歌搜索告诉它有一个“upcase”函数,然后检查两个字符串是相同的吗?如果是,那么原始的必须是所有的优势:P