2013-06-26 9 views
12

Ich bin auf der Suche nach einem Äquivalent von replace-regexp-in-string, die nur Literal-Strings, keine regulären Ausdrücke verwendet.Suche nach einer Replace-in-String-Funktion in elisp

(replace-regexp-in-string "." "bar" "foo.buzz") => "barbarbarbarbarbarbarbar" 

Aber ich will

(replace-in-string "." "bar" "foo.buzz") => "foobarbuzz" 

ich verschiedene replace-* Funktionen ausprobiert, aber kann es nicht herausgefunden.

bearbeiten

Im Gegenzug für die aufwendigen Antworten, die ich zu Benchmark ihnen entschieden (ja, ich weiß, alle Benchmarks sind falsch, aber es ist immer noch interessant).

Die Ausgabe von benchmark-run ist (time, # garbage collections, GC time):

(benchmark-run 10000 
    (replace-regexp-in-string "." "bar" "foo.buzz")) 

    => (0.5530160000000001 7 0.4121459999999999) 

(benchmark-run 10000 
    (haxe-replace-string "." "bar" "foo.buzz")) 

    => (5.301392 68 3.851943000000009) 

(benchmark-run 10000 
    (replace-string-in-string "." "bar" "foo.buzz")) 

    => (1.429293 5 0.29774799999999857) 

replace-regexp-in-String mit einem zitierte regexp gewinnt. Temporäre Puffer sind bemerkenswert gut.

bearbeiten 2

Jetzt mit Compilation! Hatte 10x mehr Iteration zu tun:

(benchmark-run 100000 
    (haxe-replace-string "." "bar" "foo.buzz")) 

    => (0.8736970000000001 14 0.47306700000000035) 

(benchmark-run 100000 
    (replace-in-string "." "bar" "foo.buzz")) 

    => (1.25983 29 0.9721819999999983) 

(benchmark-run 100000 
    (replace-string-in-string "." "bar" "foo.buzz")) 

    => (11.877136 86 3.1208540000000013) 

haxe-Ersetzen-String sieht gut aus

+1

Die Zeit für 'haxe-replace-string' ist wahrscheinlich so schlecht, weil Sie sie nicht bytekompiliert haben? 'loop' Makro macht das Kompilieren wirklich zu einem Muss, ansonsten ist es sehr langsam. –

+0

mit einigen weiteren Nummern aktualisiert – spike

+1

(ersetzen-regexp-in-string "\\." "Bar" "foo.buzz") => "foobarbuzz" – vitaly

Antwort

14

Try this:

(defun replace-in-string (what with in) 
    (replace-regexp-in-string (regexp-quote what) with in nil 'literal)) 
+3

Der vorletzte paren sollte nach draußen bewegt werden, aber ansonsten funktioniert das ja . Es gibt keinen eingebauten dafür? Es scheint, als würde so eine seltsame Sache ausgelassen. – spike

+0

@spike Ich habe irgendwo gelesen, dass der vorgeschlagene Weg ist, einen temporären Puffer zu erstellen, kopieren Sie die Zeichenfolge dort und zu 'ersetzen-Zeichenfolge 'auf dem Puffer. Es wäre interessant, wenn es so schneller wäre. –

+1

@spike - behoben. –

3

ich nicht für diese hoffen würde, schneller sein:

(defun haxe-replace-string (string string-a string-b) 
    "Because there's no function in eLisp to do this." 
    (loop for i from 0 upto 
     (- (length string) (length string-a)) 
     for c = (aref string i) 
     with alen = (length string-a) 
     with result = nil 
     with last = 0 
     do (loop for j from i below (+ i alen) 
       do (unless 
         (char-equal 
         (aref string-a (- j i)) 
         (aref string j)) 
         (return)) 
       finally 
       (setq result 
         (cons (substring string last (- j alen)) result) 
         i (1- j) last j)) 
     finally 
     (return 
     (if result 
      (mapconcat 
       #'identity 
       (reverse (cons (substring string last) result)) string-b) 
      string)))) 

Becasue replace-regexp-in-string ist eine native Funktion, aber Sie wissen nie ... Wie auch immer, schrieb ich dies vor einiger Zeit für aus irgendeinem Grund, so, wenn Sie so wollen den Vergleich der Leistung füllen - Sie sind willkommen :)

Eine andere Idee, zu versuchen, temporäre Puffer:

(defun replace-string-in-string (what with in) 
    (with-temp-buffer 
    (insert in) 
    (beginning-of-buffer) 
    (while (search-forward what nil t) 
     (replace-match with nil t)) 
    (buffer-string))) 
8

s.el String-Manipulation Bibliothek hat s-replace Funktion:

(s-replace "." "bar" "foo.buzz") ;; => "foobarbuzz" 

Ich empfehle die Installation s.el von Emacs Package Manager, wenn Sie mit Strings in Ihrem Elisp arbeiten.

Verwandte Themen