ruby-on-rails
  • ruby
  • regex
  • gsub
  • 2009-08-17 15 views 9 likes 
    9

    Szybkie tło: Mam ciąg zawierający odniesienia do innych stron. Strony są połączone z użyciem formatu: "# 12". Hash, po którym następuje identyfikator strony.Ruby, gsub i regex

    Powiedz, mam następujący ciąg:

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

    już wiem identyfikatory stron, które wymagają linkami:

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

    Jak pętli identyfikatorów strona może i link # 12 i # 125 do ich stron? Problem Zabrakło mi na to, czy mam następujące (w szynach):

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

    Działa to dobrze dla # 12 ale łączy „12” część nr 125 do strony z ID 12.

    Każda pomoc będzie świetna.

    Odpowiedz

    12

    jeśli indeksy zawsze kończy się na granicy słów, które można dopasować:

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

    trzeba tylko dodać słowo symbol granica \b na wzór wyszukiwania, nie jest konieczne dla wzoru zastępczego.

    +0

    cudowny. Nie wiedziałem o \ b. Pan, jesteś ratownikiem. –

    21

    Zamiast wydobycia identyfikatory, a następnie zastąpienie ich, można po prostu znaleźć i zastąpić je jednym zamachem:

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

    Nawet jeśli nie można pominąć etap ekstrakcji, bo trzeba gdzieś identyfikatory w przeciwnym razie powinno to być znacznie szybsze, ponieważ nie musi przechodzić przez cały ciąg znaków dla każdego identyfikatora.

    PS: Jeśli str nie jest dalej od nigdzie indziej, można użyć str.gsub! zamiast str = str.gsub

    +2

    To jest właściwe rozwiązanie. – Magnar

    +1

    Jest to efektywne, ale w zależności od treści tekstu może powodować fałszywe alarmy. Wyobraź sobie, że ma on 125 stron do odniesienia, a w tekście stron (numery porządkowe, itp.) Są ciągi takie jak # 112325, które w przypadku każdego fałszywego pozytywu dałyby link do martwej strony. Podczas wyszukiwania przy użyciu listy stron i granic słów nie jest niezawodny, jest on bardziej wytrzymały niż to rozwiązanie, pomimo jego elegancji. – Pinochle

    +2

    Jeśli był ciąg, taki jak # 112325, byłby on w tablicy page_ids, więc w ten sposób wygenerowałby martwe łącze. Zauważ, że mój gsub używa tego samego wyrażenia regularnego co skanowanie OP. Więc znajdą dokładnie te same identyfikatory. – sepp2k

    Powiązane problemy