在对 Rails 的正则表达式和字符串扫描进行了一些研究之后,我想出了我的问题的答案。这是我现在使用的方法的代码:
def replace_slugs(text, characters)
# Regexp that will recognize wiki urls with pipes and return 2 items
# It also ignores wiki urls that don't have a pipe
# /\[\[:([^|\]]*)?\|([^\]]+)\]\]/
links = text.scan(/\[\[:([^|\]]*)?\|([^\]]+)\]\]/)
for link in links do
slug = link[0]
title = link[1]
# I'm stripping out the whitespace when I do my find and for my link
# This makes it so you can have whitespace before and after the pipe
# e.g. [[:slug|Title]] [[:slug | Title]] [[:slug | Title]]
ch = characters.find_by_slug(slug.strip)
text.gsub!("[[:#{slug}|#{title}]]", link_to(title.strip,
adventure_character_path(ch.adventure, ch))) if ch
end
slugs = text.scan(/\[{2}:([^\]]*)\]{2}/).map{|s|s[0]}
characters.where(:slug => slugs).each{|ch| text.gsub!("[[:#{ch.slug}]]",
link_to(ch.name, adventure_character_path(ch.adventure, ch)))}
return text
end
Because of the way I formulated the regexp, I had to make two separate calls for when there are both links of form [[:slug]] and [[:slug|Title]]. Because of that, I've added an extra variable in the method called characters. This is so I can pass in an array of characters from where I call the method instead of having to search the entire database as that could get expensive and I already know the list of characters I want to use.