我試圖讓從comint-mode
派生的劣勢模式自動「鏈接」輸出中file:line:col
的兩個變體。使用(?:x)|(?:y)重新搜索後退不起作用?
這樣做,我有一個正則表達式在非捕獲組中有兩個子模式,加入了|
。每個子模式正好有三個捕捉組:
(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」的示例輸入不匹配,第二個子模式接下來嘗試並匹配。
我很難過。我是否誤解了一般的正則表達式,或者這對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))))
你可能會發現[再生成器(http://www.emacswiki.org/emacs/ReBuilder)和[RX](http://www.emacswiki.org/emacs/rx)有用 –
當然。在這種情況下,我的正則表達式本身實際上是正確的,但在我的代碼中,使用結果讓我對捕獲組的編號感到愚蠢。 –