2009-08-17 13 views
9

Quick Hintergrund: Ich habe eine Zeichenfolge, die Verweise auf andere Seiten enthält. Die Seiten sind mit dem Format "# 12" verknüpft. Ein Hash gefolgt von der ID der Seite.Ruby, Gsub und Regex

sagen, dass ich die folgende Zeichenfolge haben:

str = 'This string links to the pages #12 and #125' 

Ich weiß schon, die IDs der Seiten, die brauchen Verknüpfung:

page_ids = str.scan(/#(\d*)/).flatten 
=> [12, 125] 

Wie kann ich eine Schleife durch die Seite-IDs und verknüpfen Sie die # 12 und # 125 zu ihren jeweiligen Seiten? Das Problem, das ich habe laufe in ist, wenn ich die folgende (in Schienen):

page_ids.each do |id| 
    str = str.gsub(/##{id}/, link_to("##{id}", page_path(id)) 
end 

Dies funktioniert gut für # 12, aber es verbindet den „12“ Teil # 125 auf der Seite mit der ID von 12.

Jede Hilfe wäre genial.

Antwort

12

wenn Ihre Indizes immer an Wortgrenzen enden, können Sie das Spiel:

page_ids.each do |id| 
    str = str.gsub(/##{id}\b/, link_to("##{id}", page_path(id)) 
end 

Sie brauchen nur das Wort Grenze Symbol \b auf dem Suchmuster hinzuzufügen, ist es nicht erforderlich, dass die Ersetzungsmuster.

+0

verwenden können. Ich wusste nicht über \ b. Sie, mein Herr, sind ein Lebensretter. –

21

Statt die IDs zuerst zu extrahieren und sie dann zu ersetzen, können Sie einfach finden und ersetzen Sie sie in einem Rutsch:

str = str.gsub(/#(\d*)/) { link_to("##{$1}", page_path($1)) } 

Auch wenn Sie nicht den Extraktionsschritt auslassen können, weil Sie die IDs irgendwo brauchen Sonst sollte dies viel schneller sein, da es nicht für jede ID die gesamte Zeichenfolge durchlaufen muss.

PS: Wenn str nicht von irgendwo anders bezeichnet wird, Sie Marvelous str.gsub! statt str = str.gsub

+2

Dies ist die richtige Lösung. – Magnar

+1

Dies ist effizient, kann aber, je nach Inhalt des Textes, zu Fehlalarmen führen. Stellen Sie sich vor, dass er 125 Seiten hat, auf die verwiesen wird, und dass im Text der Seiten Zeichenfolgen wie # 112325 enthalten sind (Bestellnummern usw.). Dies würde bei jedem Falsch-Positiven einen Link zu einer toten Seite erzeugen. Während die Suche mit der Liste der Seiten und Wortgrenzen nicht narrensicher ist, ist sie trotz ihrer Eleganz robuster als diese Lösung. – Pinochle

+2

Wenn es eine Zeichenfolge wie # 112325 gäbe, würde sie im Array page_ids liegen, also würde es in beiden Fällen einen toten Link erzeugen. Beachten Sie, dass mein gsub die gleiche Regex wie der OP-Scan verwendet. So werden sie genau die gleichen IDs finden. – sepp2k