类似下面这个有没有更简单的写法:
"\\(\\sw\\|\\s_\\)\\{3,6\\}"
类似下面这个有没有更简单的写法:
"\\(\\sw\\|\\s_\\)\\{3,6\\}"
你实际的需求是什么?匹配 3 - 6 长度的符号么?如果是这样的话,一个比较简单写法是:
\_<.{3,6}\_>
但它不准确,会产生多余的匹配,比如下面会匹配到 foo
和 x y
。
(defun foo (x y z))
准确的写法大概就是你的写法,只是要还要限定 Symbol 的开头和结尾:
\_<\(?:\sw\|\s_\)\{3,6\}\_>
楼主是在找这种写法?
(rx (repeat 3 6 (or
(syntax word) ;; => \\sw
(syntax symbol) ;; => \\s_
))) ;; => \\(?:\\sw\\|\\s_\\)\\{3,6\\}
mei you
本来是想问一下有没有可以用单个元素表示一个symbol字符的, 这样不需要那么多括号, 方便后面跟{}, *, +等,类似\sw, 最近在定制go-mode的语法高亮, 感觉编程类mode里用symbol的频率非常高, 每次都要写那么长, 感觉很不方便
就是希望短一点, 或者类似[:symbol:]这种也可以, 好像是不支持.
rx这种方式挺直观啊.
再补充一点:\\{3,6\\}
可能不会按照你的预期工作,它能跳过长度小于 3 的符号,但是长度超过 6 的符号仍然会被匹配到。这时就要如 2#楼 所说,用 \\<_ ... \\_>
再包裹一层:
(let ((reg (rx symbol-start
(repeat 3 6 (or (syntax word)
(syntax symbol)))
symbol-end)))
(list
reg ;; => ("\\_<\\(?:\\sw\\|\\s_\\)\\{3,6\\}\\_>"
(string-match-p reg "fo") ;; nil
(string-match-p reg "foo") ;; 0
(string-match-p reg "foobar") ;; 0
(string-match-p reg "foobar ") ;; 0
(string-match-p reg "foobar1"))) ;; nil)
没发现有现成的,不过可以试试自己添加个 Category,比如用 x
代表所有能组成 Symbol 的字符,然后就可以用 \cx
了。
(info "(elisp) Regexp Backslash")
(注意最后一句话)
‘\cC’
matches any character whose category is C. Here C is a character
that represents a category: thus, ‘c’ for Chinese characters or ‘g’
for Greek characters in the standard category table. You can see
the list of all the currently defined categories with ‘M-x
describe-categories <RET>’. You can also define your own
categories in addition to the standard ones using the
‘define-category’ function (*note Categories::).
\s_表示连接符,比如c里面的下划线字符,\sw表示word,两者合起来组成symbol,所以两个经常写一起,比较长。
长度范围只是举个例子,个别情况下用到。
这个竟然也可以扩展
简单试了下确实可以扩展
(defvar chunyang-c-category-table
(let ((table (make-category-table)))
(define-category ?s "C identifiers characters" table)
(dolist (char (seq-filter (lambda (char)
(string-match "[-_0-9A-Za-z]" (string char)))
(number-sequence 0 127)))
(modify-category-entry char ?s table))
table))
(set-category-table chunyang-c-category-table)
然后就能用 \cs
了,比如:
\_<\cs\{3,6\}\_>
好像是可以, 不过我把方括号里第一个减号去掉了不知道怎么实际还包括减号.
印象中在major-mode的实现文件里, \c正则好像比较少用, 一般都是用\s
“Categories” provide an alternate way of classifying characters syntactically.
看了一下文档里syntax table和catalog table的区别, 一个字符只能有一个syntax, 而可以属于多个catalog. 所以基于前者是没法实现symbol了, 一个字符要么是\sw要么是\s_. 后者理论上可以实现这种效果.
随便一提,如果要匹配一个完整的 Symbol,可以用 \_<.+?\_>
,无需表达「一个 Symbol 字符」。
简单情况是可以, 但很多情况下不方便用, 比如c语言的符号不能数字开头
试图用正则表达式来准确无误地匹配 Symbol 即便假设有可能做到,也多半麻烦,更谈不上方便地直接输入了。