2014-09-10 51 views
2

我的問題是關於函數clojure.string/split。人們可以指定分割爲函數的最大數量,它就像一個魅力:分割字符串與結束的正則表達式

user> (clojure.string/split "1{1,2{3,4},5}6" #"\{" 2) 
;; => ["1" "1,2{3,4},5}6"] 

然而,函數遍歷由左到右的字符串。有時我希望它從右到左遍歷一個字符串形式(從結尾):

user> (clojure.string/split "1{1,2{3,4},5}6" #"\}" 2) 
;; => ["1{1,2{3,4" ",5}6"] 
;; desired result: ["1{1,2{3,4},5" "6"] 

如何使用正則表達式實現它?

回答

1

你可以嘗試使用你的具體情況負前瞻,以確保有一前一後沒有更多}你在分裂:

user> (clojure.string/split "1{1,2{3,4},5}6" #"\}(?![^\}]*\})" 2) 

(?![^\}]*\})是負先行,將防止匹配,如果在}匹配後還有另一個}。我使用的是否定類[^\}]*使它比使用.*更快,因爲我不熟悉clojure,所以我不完全確定是否需要逃跑。通常情況下,您可以安全地使用\}(?![^}]*\}),但無論是否需要轉義都可以使用。

+0

哇,它的工作原理,但我不明白如何:-(你說你正在使用'否定班',使其更快,你可以發佈更慢,更簡單的變種(只是開始挖掘)。轉義字符,因爲clojure使用[java正則表達式](http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)並且沒有它clojure拋出'PatternSyntaxException'。 – Mark 2014-09-10 12:35:11

+1

@Mark速度的差異並沒有太大的不同,但是這裏是:'#「\}(?!。*?\})」'負向預測的工作方式是,如果內部匹配,匹配失敗。 '。*?\}'匹配時,匹配將失敗,'。*?'將匹配任何*字符,但它一次檢查一個字符,這更適用於字符串較短的情況。 \}(?!。* \})「'(沒有'?')會做同樣的事情,除非這個函數在最後一個'}接近字符串末尾時工作,並且如果th兩個'}'在一個很長的字符串的開頭。 ''[^ \}] *'在任何情況下都可以快速工作。 – Jerry 2014-09-10 12:48:10

+0

關於轉義,我說過,因爲包含Java的大多數引擎在將元字符放入字符類時不需要轉義,因此:'[\}]'與'[}]'相同。但是有太多的東西在那裏,一個永遠不能太確定:) – Jerry 2014-09-10 12:49:43