I'm trying to build a function but having trouble with the regex. Specifically, I want to match capital letters only.

This function is supposed to capitalize words that are in lowercase (theThe) but not touch words that are already in uppercase (like #+STARTUP: or * TODO).

(defun capitalize-unless-org-heading ()
(looking-at "\*")
(looking-at "[\n\t ]*\\*") ; don't capitalize an org heading
(looking-at "* TODO") ; don't capitalize an org todo heading
(looking-at "[\n\t\ ]*#+") ; don't capitalize org options like #+STARTUP:
(looking-at "[\n\t\ *[A-Z]") ; don't capitalize any word that might be all uppercase
(capitalize-word 1))

If it matters, case-fold-search is set to t so I can search for text in my buffers without worrying about case. How do I build a regex to search for uppercase letters only?


You can temporarily bind case-fold-search using let:

(let ((case-fold-search nil))
  (looking-at "[\n\t ]*[A-Z]"))

Also, I changed your regexp for matching whitespace and newlines -- a ] was missing and you don't need the backslash before the space.

Here is the corrected code, also incorporating Zorgoth's edits below.

(defun capitalize-unless-org-heading ()
  (unless (or
            (looking-at "[\n\t ]*\\*")
            (let ((case-fold-search nil))
              (looking-at "[\n\t ]*[A-Z]")) 
            (looking-at "[\n\t ]*#\\+")) 
    (capitalize-word 1)))
| improve this answer | |

Be aware that there are some mistakes in that code. I don't know if \* means anything at all in this context (\\* does). You also need to escape + with two backslashes as that has a meaning in emacs regexps. And there is a * at the beginning of a string that I presume was intended to be after a space.

Apart from that, the answer above answers the main question you had.

If you wanted a more general way of getting to the next word for other purposes you could use [^A-Za-z]* to see past all non-letters.

| improve this answer | |
  • Thank you! Is this correct now? (defun capitalize-unless-org-heading () (interactive) (unless (or (looking-at "[\n\t ]\\*") (let ((case-fold-search nil)) (looking-at "[\n\t ]*[A-Z]")) (looking-at "[\n\t ]*#\\+") ) (capitalize-word 1)) ) – incandescentman Dec 9 '15 at 1:21
  • 1
    There is a * missing after the first [\n\t ] group, which mean that you will only match exactly one whitespace character. – Lindydancer Dec 9 '15 at 8:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.