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 が示すように、そうしないと、Emacs が大文字と小文字を区別しない検索として扱う可能性がcase-fold-searchある場合に、これを行う必要があります。nilただしstring-match-p、一致データの変更を回避できるため、さらに優れています。(Emacs は一致した後もそのデータを保持します。使用するstring-matchと上書きされ、関数を使用するコードが壊れる可能性があります。)

  3. 別の問題は、正規表現自体です。using"^...$"は、Emacs が一致する内容の行を探すことを意味します。文字列に改行文字が含まれていると、偽の結果が返される可能性があります。文字列の先頭と末尾のみに一致する backslash-unquote と backslash-quote を使用する必要があります。

したがって、正しいバージョンは次のとおりです。

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

(ところで、Emacs Lisp での通常の規則は、-p述語に a を使用することです。 のように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.elには次のものがありますs-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 についてあまり知りませんが、Google で簡単に検索すると、「大文字と小文字を区別する」機能があることがわかり、2 つの文字列が同じかどうかを確認します)。 ? もしあれば、元のものはすべて大文字でなければなりません:P

于 2010-01-25T02:21:57.560 に答える