11

Q: how does one test string equality but ignore case?

I've got a situation in which I'd like to compare strings but ignore case. Case is significant for string-equal, and apparently is insensitive to case-fold-search:

(string-equal "string" "StrinG")        ; => nil
(let ((case-fold-search t))
  (string-equal "string" "StrinG"))     ; => nil

I could always preprocess the strings (say, with downcase) before comparing them:

(string-equal (downcase "string")
              (downcase "StrinG"))      ; => t

But that seems like overkill to do two extra function calls every time. Have I overlooked the relevant predicate function somewhere?

Dan
  • 32,584
  • 6
  • 98
  • 168
  • I used compare-strings and found the following problem. (setq str "title") (cond (compare-strings str "authortitle") do something.) (compare-strings str "title") do something else.) The first compare-strings returns a positive value implying true which is not what I want. Therefore I used the downcase suggestion. –  May 17 '15 at 15:30

3 Answers3

10

You can use compare-strings:

(compare-strings STR1 START1 END1 STR2 START2 END2 &optional IGNORE-CASE)

Use nils for starts and ends to use the whole strings.

choroba
  • 1,925
  • 10
  • 16
  • Thanks; I'd seen that one but didn't realize that one could use `nil`s as you mentioned. I'll leave the question open a little longer in case there's another option that doesn't require 4 extra `nil`s in a function call. – Dan Mar 30 '15 at 11:38
8

Another short alternative:

(cl-equalp "string" "strinG")      ; => t
(cl-equalp "strinG" "this string") ; => nil 
(cl-equalp "word" "buzzword")      ; => nil

equalp from the deprecated cl library is another alternative. From (documentation 'cl-equalp), my emphasis in bold:

like ‘equal’, except that it accepts numerically equal numbers of different types (float vs. integer), and also compares strings case-insensitively.

dardisco
  • 189
  • 2
  • 6
  • 1
    `equalp` is not short for `cl-equalp` - `cl-equalp` is provided by the `cl-lib` library, whereas `equalp` is provided by the deprecated `cl` library. That the `cl` library defines it as an alias is an internal implementation detail. I therefore suggest you recommend `cl-equalp` over `equalp`. See [`(info "(cl) Organization")`](https://www.gnu.org/software/emacs/manual/html_node/cl/Organization.html). – Basil Apr 11 '21 at 20:49
  • Answer updated, as above. – dardisco Apr 12 '21 at 22:25
5

Use string-suffix-p:

(string-suffix-p "string" "strinG" t)

Much simpler and doesn't require 4 nils. It doesn't test if strings are equal per se ((string-suffix-p "word" "buzzword" t) ⇒ t). Although, in some cases this should be sufficient (if you have limited dictionary to check upon).

rgtk
  • 414
  • 5
  • 9
  • 2
    `(string-suffix-p "strinG" "this string" t)` also returns `t`. This is not what the OP wants. I suggest you either modify or delete this answer. – Tobias Jan 28 '16 at 22:09
  • Answer updated. I will leave it because `string-{prefix,suffix}-p` can useful in many ways: test if word at point is given keyboard (in SQL for example where case can be mixed) etc. – rgtk Jan 29 '16 at 15:31