2013-06-18 309 views
2

在emacs lisp中,我只知道函數string-match[-p],但我不知道將字符串與字符串進行匹配的方法。emacs lisp中的字符串匹配匹配任意字符串

E.g.假設我有一個由某個函數生成的字符串,並且想知道另一個字符串是否包含它。在很多情況下,string-match-p會正常工作,但是當生成的字符串包含regexp語法時,它將導致意外的行爲,甚至可能會在包含的正則表達式語法無效的情況下崩潰(例如,不平衡的帶引號的括號爲\(,\))。

  1. emacs lisp中的某些函數與string-match-p類似,但不解釋正則表達式語法?
  2. 由於在C中實現了正則表達式匹配,我假設匹配正確的正則表達式比某些substring/string=循環更快;有沒有一種方法可以將任意字符串轉換爲與該字符串匹配的正則表達式,並且只有該字符串?

回答

6

您是在查找regexp-quote

文檔說:

(regexp-quote STRING) 

Return a regexp string which matches exactly STRING and nothing else. 

而且我不知道你在#2假設是正確的,string=應該快了......

+2

謝謝,這在大多數情況下都有幫助。此外,對於一個68字符的查詢字符串和一個≈300字符串來在字符串中進行搜索 - 使用'regexp-quote'的實現在編譯代碼中執行速度快40倍,未編譯代碼執行速度快60倍。對於「string-starts-with」,「string-ends-with」,然而,一個天真的'(string =(substring ...)...)'實現在編譯代碼中快了4倍(未編譯代碼慢了4倍)爲相似的輸入大小。 – kdb

0

也許cl-mismatch,模擬到Common Lisp的mismatch功能?示例如下:

(mismatch "abcd" "abcde") 
;; 4 
(mismatch "abcd" "aabcd" :from-end t) 
;; -1 
(mismatch "abcd" "aabcd" :start2 1) 
;; nil 

對不起,我第一次不明白這個問題。如果您想知道該字符串是否是另一個字符串的子字符串(可能從搜索字符串中的任何索引開始),那麼您可以使用cl-search,這也是Common Lisp search函數的一個模擬。

(search "foo\\(bar" "---foo\\(bar") 
;; 3 
4

根據@ trey-jackson的推薦使用regexp-quote,或根本不使用字符串。

Emacs未優化字符串處理;它針對緩衝區進行了優化。所以,如果你操作文本,你可能會發現它更快到create a temporary buffer,在那裏插入你的文本,然後用search-forward在那個緩衝區中找到你的固定字符串(非正則表達式)。

+2

在我的系統上,'with-temp-buffer'的開銷大約是2e-6秒(0.2秒用於執行'(with-current-buffer(+ 1 1))'10,000次。雖然可以忽略不計,但對於短字符串(≈10-30個字符)而言,開銷比字符串函數(內建的,我試過的和我自己編寫的)的時間要大100-1000倍。我會相信你,但是,對於長字符串緩衝提供更好的性能,所以謝謝你的答案! – kdb