其实就是调用微软的 VBScript Regular Expressions 引擎。
但是那里的代码有个地方写反了。命名格式也不统一。我修改了一下。
定义了三个函数:提取、详细提取、替换。
(defun regex-extract (pat str key / regex S tmp str1)
;; 提取正则表达式匹配到的内容
;; pat 正则表达式 str 字符串
;; pat 中 \ 使用 \\
;; key "igm" i(Ignorecase)忽略大小写 g (Global)全局匹配 m (Multili) 多行模式
;; 注意:一般使用全局匹配 g
;; 可组合使用或单独使用 或置空 ""
(vl-load-com)
(setq regex (vlax-create-object "Vbscript.RegExp")) ;引用正则表达式控件
(if (wcmatch key "*i*,*I*")
(vlax-put-property regex "IgnoreCase" 1) ;忽略大小写
(vlax-put-property regex "IgnoreCase" 0) ;不忽略大小写
)
(if (wcmatch key "*g*,*G*")
(vlax-put-property regex "Global" 1) ;匹配方式,全文字匹配
(vlax-put-property regex "Global" 0)
)
(if (wcmatch key "*m*,*M*")
(vlax-put-property regex "Multiline" 1) ;多行模式
(vlax-put-property regex "Multiline" 0)
)
(vlax-put-property regex "Pattern" pat)
(setq s (vlax-invoke-method regex "Execute" str))
;;将规则运用到STR字符,得到提取出的文字内容
(VLAX-FOR tmp s ;遍历集合对象
(setq str1 (cons (vlax-get-property tmp "value") str1))
)
;;将内容转换为LISP语言就可以直接观察了
(vlax-release-object regex)
(REVERSE str1)
)
(defun regex-search (pat str key / REGEX S tmp POS LEN string str1)
;; 提取正则表达式匹配到的内容,输出其 位置(从0开始编号),长度,值
;; pat 正则表达式 str 字符串
;; pat 中 \ 使用 \\
;; key "igm" i(Ignorecase)忽略大小写 g (Global)全局匹配 m (Multili) 多行模式
;; 注意:一般使用全局匹配 g
;; 可组合使用或单独使用 或置空 ""
(vl-load-com)
(setq regex (vlax-create-object "Vbscript.RegExp"))
(if (wcmatch key "*i*,*I*")
(vlax-put-property regex "IgnoreCase" 1) ;忽略大小写
(vlax-put-property regex "IgnoreCase" 0) ;不忽略大小写
)
(if (wcmatch key "*g*,*G*")
(vlax-put-property regex "Global" 1) ;匹配方式,全文字匹配
(vlax-put-property regex "Global" 0) ;只检查第一处出现的位置
)
(if (wcmatch key "*m*,*M*")
(vlax-put-property regex "Multiline" 1) ;多行模式
(vlax-put-property regex "Multiline" 0) ;单行模式
)
(vlax-put-property regex "Pattern" pat)
(setq s (vlax-invoke regex 'Execute str))
(vlax-for tmp s
(setq pos (vlax-get-property tmp "FirstIndex")
len (vlax-get-property tmp "Length")
string (vlax-get-property tmp "value")
)
;;; Match对象和Matches集合只能通过 RegExp对象的Execute方法来创建,该方法实际上返回了Match
;;; 对象的集合Matches。所有的Match对象属性都是只读的。每个Match对象提供了被正则表达式搜索
;;; 找到的匹配字符串的开始位置、长度,字符串本身等信息,通过Match对象的属性供用户访问。
;;; FirstIndex在搜索字符串中匹配的位置。Length匹配字符串的长度。Value找到的匹配字符串。
(setq str1 (cons (list pos len string) str1))
(princ (strcat "\n文字位置 = "
(itoa pos)
" 文字长度 = "
(itoa len)
" 值 = \""
string
"\""
)
)
)
(vlax-release-object RegEx)
(reverse str1)
)
(defun regex-replace (pat str str1 key / regex S str2)
;; pat 正则表达式 str 字符串 str1 替换的字符串
;; pat 中 \ 使用 \\
;; key "igm" i(Ignorecase)忽略大小写 g (Global)全局匹配 m (Multili) 多行模式
;; 注意:一般使用全局匹配 g
;; 可组合使用或单独使用 或置空 ""
;; 返回替换后的字符串
(vl-load-com)
(setq regex (vlax-create-object "Vbscript.RegExp")) ;引用正则表达式控件
(if (wcmatch key "*i*,*I*")
(vlax-put-property regex "IgnoreCase" 1) ;忽略大小写
(vlax-put-property regex "IgnoreCase" 0) ;不忽略大小写
)
(if (wcmatch key "*g*,*G*")
(vlax-put-property regex "Global" 1) ;匹配方式,全文字匹配
(vlax-put-property regex "Global" 0) ;只检查第一处出现的位置
)
(if (wcmatch key "*m*,*M*")
(vlax-put-property regex "Multiline" 1) ;多行模式
(vlax-put-property regex "Multiline" 0) ;单行模式
)
(vlax-put-property regex "Pattern" pat)
(setq STR2 (vlax-invoke-method regex "Replace" STR STR1))
(vlax-release-object regex)
STR2
)
替换的时候,用 $1 $2 $3...表达()捕获的内容。