2010-10-06 17 views
5

Scala, bir çok satırlı dizenin sol tarafını belirtilen bir sınırlayıcıya (varsayılan: "|") kaldıran stripMargin adlı bir yöntem sunar.Clojure şeridiMargin

"""|Foo 
    |Bar""".stripMargin 

döndürür dize

Foo 
Bar 

Clojure benzer bir işlevi var mı: İşte bir örnek? Eğer değilse, onu nasıl uygularsınız (en işlevsel şekilde)?

Teşekkürler.

UPDATE: Verdiğim örnek tam değil. stripMargin yöntem ayrıca sınırlayıcı sonra boşluk korur:

"""|Foo 
    | Bar""".stripMargin 

Foo 
    Bar 
+0

Benim cevabım sınırlayıcı _before_ boşluk şerit 'ltrim' kullanır. –

cevap

4

Orada yerleşik böyle bir fonksiyondur ancak kolayca yazmak:

İşte
(use '[clojure.contrib.string :only (join, split-lines, ltrim)]) 

(defn strip-margin 
    ([s d] (->> s split-lines (map ltrim) (map #(.replaceFirst % d "")) (join "\n"))) 
    ([s] (strip-margin s "\\|"))) 

bazı "gerçek: İşte

user=> (use '[clojure.contrib.string :only (join, split-lines, ltrim)]) //' 
nil 
user=> (->> "|Foo\n |Bar" split-lines (map ltrim) 
    (map #(.replaceFirst % "\\|" "")) (join "\n")) 
"Foo\nBar" 
+0

Scala'nın stripMargin'inin herhangi bir sınırlayıcı karakterle çalıştığını, ancak karakterin satırdaki ilk boş olmayan karakter olmasını da beklediğini unutmayın. –

+0

@ abhinv4: Yukarıdaki güncellemeye bakın. Bu, sınırlayıcının ardından gelen boşlukları destekliyor gibi görünüyor: '(- >>" | Foo \ n | Bar "bölünmüş çizgiler (map # (. ReplaceFirst%"^\\ s * \\ | "" ")) \ n ")) ==>' "Foo \ n Bar" ' – Ralph

+0

@Ralph:" Bu, sınırlayıcıdan sonra önde gelen boşlukları destekliyor gibi görünüyor. " Sorunuza göre istediğin bu değil mi? –

2

hızlı googling varolan herhangi fonksiyonlarını dönmedi dize döndürür, ancak burada sorun benim girişimidir. Özel sınırlayıcıları desteklemez ve çok hızlı bir şekilde optimize edilmez.

(use '[clojure.contrib.str-utils :only (re-split re-sub str-join)]) 

(defn strip-margin [s] 
    (let [lines (seq (re-split #"\n" s))] 
    (str-join "\n" 
     (for [line lines] 
     (re-sub #"^\s*\|" "" line))))) 
2

benim komple çözüm, yukarıdaki cevapları toplanan "örnek giriş ve çıkış:

(println 
    (strip-margin "|<?xml version='1.0' encoding='utf-8'?> 
       |<people> 
       | <person> 
       | <name>Joe Smith</name> 
       | </person> 
       |</people>")) 

==>

<?xml version='1.0' encoding='utf-8'?> 
<people> 
    <person> 
    <name>Joe Smith</name> 
    </person> 
</people> 
nil 

Tüm katkıda bulunanlara teşekkür ederiz.

1

Ayrıca tek regexp ile yapabilirsiniz:

(use '[clojure.contrib.string :only (replace-re)]) 

(def test-string 
"|<?xml version='1.0' encoding='utf-8'?> 
       |<people> 
       | <person> 
       | <name>Joe Smith</name> 
       | </person> 
       |</people>") 


(replace-re #"(^\|)|(.+\|)" "" test-string)) 
+1

Jamie Zawinski'nin ünlü olarak söylediği gibi bunu seviyorum: 'Bazı insanlar, bir problemle karşılaştıklarında,' Biliyorum, normal ifadeler kullanacağım 'diye düşünüyorum. Şimdi onların iki problemi var.' :-) – Ralph

+0

Katılıyorum, son birkaç gün boyunca regexps ile çok çalıştım ve kendini bacakta vurmak çok kolay ... Bu site http://gskinner.com/RegExr/ yardımcı olsa da –