Table of Contents
前言
要想自己写一些使用的插件,或者更简单一点,写一些使用的配置,正则表达式都是一道绕不过去的坎啊。
之前总是看别人的例子照葫芦画瓢,因此总是要让自己的想法去迁就别人的正则表达式,这次打算狠狠心,彻底掌握它。
语法
用""来引用特殊字符,包括"",在lisp中每一个"""都必须写成两个。
基本匹配
符 | 含义 | 例子 |
"." | 匹配单个字符 | "a.b"表示'a'开始'b'结尾的3个字符 |
"*" | 前导字符重复任意次 | "ab*"匹配"a" "ab" "abb"等 |
"+" | 前导字符重复至少一次 | "ab*"匹配"ab" "abb"等 |
"?" | 前导字符重复至多一次 | "ab*"仅仅匹配"a" "ab" |
"{N}" | 前导字符重复N次 | "a{4}"仅仅匹配"aaaa" |
"{N,M}" | 前导字符重复N-M次 | "a{1,2}"仅仅匹配"a"或者"aa" |
字符集
- "[ab]"匹配"a"或"b"。
- "[a-z]"匹配小写字母。
- "[a-z0-9(%.]"匹配小写字母或数字或")"或"%"或"."。
- "]","-"和"^"的位置分别在最前,最后,非最前。
- "[a]"表示除去a的所有字符。
行匹配
- "^":行首匹配,如"abc"匹配在行首的"abc"。
- "(":行首匹配,如"a+)"匹配在行首的一个或多个"a"的串。
"|"
或匹配,"abc|[0-9][0-9]"匹配"abc"或者"00"-"99"。
"( ... )"
分组功能:
- 围住""|"的选择项,以实现别的操作(类似于C语言中的优先级)。例如“(ab|ac)d”匹配 “abd”或“acd”。
- 围住复杂表达式,然后把他当成单个字符。例如"(ab){2}"表示"abab"。
空串匹配
- "":在一个词的开始或者结尾。例如"ab"匹配作为单独的词出现的"ab"
- "B":不在一个词的开始或者结尾。
- "<":在一个词的开头。
- ">":在一个词的结尾。
"s"
具体可以参考"modify-syntax-entry"函数的帮助。
- "sw":相当于"w",表示可以组成word的字符
- "s_":除word之外其它用于变量和命令名的字符
例子分析
摘自asm-mode.el的一段:
(defconst asm-font-lock-keywords (append '(("^\(\(\sw\|\s_\)+\)\>:?[ ]*\(\sw+\(\.\sw+\)*\)?" (1 font-lock-function-name-face) (3 font-lock-keyword-face nil t)) ;; label started from ".". ("^\(\.\(\sw\|\s_\)+\)\>:" 1 font-lock-function-name-face) ("^\((\sw+)\)?\s +\(\(\.?\sw\|\s_\)+\(\.\sw+\)*\)" 2 font-lock-keyword-face) ;; directive started from ".". ("^\(\.\(\sw\|\s_\)+\)\>[^:]?" 1 font-lock-keyword-face) ;; %register ("%\sw+" . font-lock-variable-name-face)) cpp-font-lock-keywords) "Additional expressions to highlight in Assembler mode.")
仅分析第一个正则表达式:
"^\(\(\sw\|\s_\)+\)\>:?[ ]*\(\sw+\(\.\sw+\)*\)?"
首先是行首匹配。然后逐个分析:
"\(\(\sw\|\s_\)+\)"
先分析里面的一对括号"\(\sw\|\s_\)",表示可以组成word(包括数字)的字符或除word之外其它用于变量和命令名的字符,即可以组成变量的字符。
"\(\(\sw\|\s_\)+\)",多个表示可以组成变量的字符,即变量。
"\>:?[ ]*"
"\>"或者至多一个":"或者多个(空格或制表符),"\>"表示词尾的空串匹配。实际上可以认为这一部分是分割符。而分割符的内容就是一个冒号或者一个空格再加上任意多个空格或制表符(包括0个)。
"\(\sw+\(\.\sw+\)*\)?"
至多一个(word加上任意多个(.word))。比如说"abc.ab.cd"