9

I've been playing around with rx lately, and I just noticed there are (at least) 3 different ways of indicating whitespaces in regular expressions.

  1. [:blank:]
  2. [:space:]
  3. \s-

What are the differences between each of them? Does it depend on the major-mode?

2

2 Answers 2

6

The [:blank:] character class matches only the SPC and TAB characters. The other two match whitespace based on the active syntax table.

There does not seem to be a difference between [:space:] and \s-. The latter is an instance of the general \scode pattern for matching based on a syntax class.

1
  • 1
    Just did a quick test modifying the syntax table in a buffer to make additional characters whitespace. Testing with regexp-builder I can confirm that both [:space:] and \s- match the additional characters as spaces.
    – glucas
    Nov 15, 2014 at 14:48
1

You can check the detailed difference for yourself with the following code:

(defun me/chars-in-class (class)
  "return a list of chars in char class `class`"
  (let ((chars nil))
    (dotimes (i 65536) ;; the absolute upperbound is 4194304 (22 bit integer) according to elisp info, but you will not find any chars in :space:/:blank:/\s- beyond the usual bound 65536
      (when (string-match-p class (char-to-string i))
        (push i chars)))
    chars))

(let* ((charlist1 (sort (me/chars-in-class "[[:blank:]]") '<)) ;; make a char list of :blank:
       (charlist2 (sort (me/chars-in-class "[[:space:]]") '<)) ;; make a char list of :space:
       (charlist3 (sort (me/chars-in-class "\\s-") '<)) ;; make a char list of \s-
       (set-list
        (sort (cl-remove-duplicates (append charlist1 charlist2 charlist3)) '<)) ;; make a "set" list with all the chars from :blank:, :space:, and \s-, without duplicates
       trio)
  (cl-loop for e in set-list
       for i from 0
       if (equal i 0)
       collect '("blank" "space" "\\s-")
       and collect 'hline
       do (setq trio nil)
       (if (equal e (car charlist3))
           (push (pop charlist3) trio)
         (push nil trio))
       (if (equal e (car charlist2))
           (push (pop charlist2) trio)
         (push nil trio))
       (if (equal e (car charlist1))
           (push (pop charlist1) trio)
         (push nil trio))
       collect trio))

If executed in a org mode source block, the above code compares side by side in a table all the chars, or rather their unicode code point ("char number"), in the three char classes in question:

| blank | space |   \s- |
|-------+-------+-------|
|     9 |     9 |     9 |
|   nil |    10 |    10 |
|   nil |    12 |    12 |
|   nil |    13 |    13 |
|    32 |    32 |    32 |
|   160 |   160 |   160 |
|  5760 |   nil |   nil |
|  8192 |  8192 |  8192 |
|  8193 |  8193 |  8193 |
|  8194 |  8194 |  8194 |
|  8195 |  8195 |  8195 |
|  8196 |  8196 |  8196 |
|  8197 |  8197 |  8197 |
|  8198 |  8198 |  8198 |
|  8199 |  8199 |  8199 |
|  8200 |  8200 |  8200 |
|  8201 |  8201 |  8201 |
|  8202 |  8202 |  8202 |
|   nil |  8203 |  8203 |
|  8239 |  8239 |  8239 |
|  8287 |  8287 |  8287 |
| 12288 | 12288 | 12288 |

So first, :space: and \s- are completely the same.

Then, what :space: has but :blank: doesn't have are the chars 10, 12, 13, and 8203 (newline, formfeed character, carriage return, and zero width space), what :blank: has but :space: doesn't have is the single char 5760 (Ogham space mark). For the rest part, they are the same, both in particular sharing the common elements SPC and TAB.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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