我正在尝试从comint-mode
派生一个低级模式,自动“链接”输出中file:line:col
的两个变体。
为此,我有一个正则表达式,在非捕获组中有两个子模式,由|
加入。每个子模式都有三个捕获组:
(concat
"\\(?:" ;; pattern 1 e.g. "; /path/to/file:1:1"
"; \\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\)"
"\\)"
"\\|"
"\\(?:" ;; pattern 2 e.g. "location: #(<path:/path/to/file> 0 1"
"location: (#<path:\\([^>]+\\)> \\([0-9]+\\) \\([0-9]+\\)"
"\\)")
匹配与第一个子模式匹配的内容。但它从不匹配与第二个子模式匹配的内容。
然而,第一个模式的存在似乎意味着第二个(?: ...)
模式永远不会匹配。如果我注释掉第一个模式,那么第二个模式将匹配。
如果我删除第一个子模式,请离开
"\\(?:" ;; pattern 2
"location: (#<path:\\([^>]+\\)> \\([0-9]+\\) \\([0-9]+\\)"
"\\)"
确实匹配,所以我知道第二个子模式是正确的。
或者,如果我保留第一个子模式,但将其更改为类似“XXX”,没有捕获:
"\\(?:" ;; pattern 1
"XXXX"
"\\)"
"\\|"
"\\(?:" ;; pattern 2
"location: (#<path:\\([^>]+\\)> \\([0-9]+\\) \\([0-9]+\\)"
"\\)"
它也有效。第一个子模式与不包含“XXXX”的示例输入不匹配,第二个子模式接下来尝试匹配。
我很难过。我是否误解了一般的regexp,或者这对Emacs来说是独一无二的吗?
更重要的背景:
(define-derived-mode inferior-foo-mode comint-mode "Inferior Foo"
...
(add-hook 'comint-output-filter-functions 'linkify)
...)
(defun linkify (str)
(save-excursion
(end-of-buffer)
(re-search-backward (concat
"\\(?:" ;; pattern 1
"; \\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\)"
"\\)"
"\\|"
"\\(?:" ;; pattern 2
"location: (#<path:\\([^>]+\\)> \\([0-9]+\\) \\([0-9]+\\)"
"\\)")
(- (buffer-size) (length str))
t)
(when (and (match-beginning 0)
(match-beginning 1) (match-beginning 2) (match-beginning 3))
(make-text-button
(match-beginning 1) (match-end 3)
'file (buffer-substring-no-properties (match-beginning 1) (match-end 1))
'line (buffer-substring-no-properties (match-beginning 2) (match-end 2))
'col (buffer-substring-no-properties (match-beginning 3) (match-end 3))
'action #'go-to-file-line-col
'follow-link t))))
答案 0 :(得分:2)
你错了。第二个非捕获组的捕获组是(match-string 4)
,(match-string 5)
,(match-string 6)
,
另请注意,
(buffer-substring-no-properties (match-beginning 1) (match-end 1))
相当于简短版本
(match-string-no-properties 1)
我会建议像:
(let ((m1 (or (match-string-no-properties 1) (match-string-no-properties 4)))
(m2 (or (match-string-no-properties 2) (match-string-no-properties 5)))
(m2 (or (match-string-no-properties 3) (match-string-no-properties 6))))
(when (and m1 m2 m3) ...
答案 1 :(得分:2)
您的正则表达式与其评论不符。
评论有#(
;正则表达式为(#
。评论在location:
之后有两个空格;正则表达式有3个空格。如果你使它们对应,那么它似乎工作正常。 E.g:
(concat
"\\(?:" ;; pattern 1
"; \\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\)"
"\\)"
"\\|"
"\\(?:" ;; pattern 2
"location: #(<path:\\([^>]+\\)> \\([0-9]+\\) \\([0-9]+\\)"
"\\)")