Regexp表达式/(\@)(.*?)(\;)/在报价中失败

时间:2015-08-05 19:42:22

标签: regex ruby-on-rails-4

我有一个帮助方法,它遍历任何给定的文本块,并替换格式为' @something;'的子串。有一个链接。它适用于我尝试过的所有测试用例,包括

@user; @user name; @user.name; @@user.name; @user*name;

但是会挂在引号上,如

@I'll fight you;

但直到那一点仍然匹配?下面,为了进行hacky调试,我有一个帮助方法,在假设的匹配的两边放置三个星号(' *'),因此上面的标记会导致

***@I'***ll fight you;

我无法弄清楚。

(如果有人有任何额外的提示和技巧,如何让它匹配像@username ;;'这样的标签,其中结束字符也是名称的一部分,lemme know我认为这可能过于复杂,而且编程更好。)

module PostsHelper

  def tag_users(content)
    # User tagging in format '@multiword name;'
    # Regexp /(\@)(.*?)(\;)/ for debugging; user configurable eventually
    start_character = '@'
    end_character = ';'
    tag_pattern = eval('/(#{start_character})(.*?)(#{end_character})/')
    name_pattern = eval('/(?<=#{start_character})(.*?)(?=#{end_character})/')

    # Iterate through all tags and replace with link
    content.gsub(tag_pattern) do
      tag = Regexp.last_match(0)
      tagged_name = tag[name_pattern, 1]
      tagged_user = User.where('lower(name) = ?', tagged_name.downcase).first
      if tagged_user
         "<a href='#{user_path(tagged_user.id)}'>@#{tagged_name}</a>"
      else
        '***' + tag + '***'
      end
    end
  end
end

编辑:我用逗号标记引号。我讨厌自己。

1 个答案:

答案 0 :(得分:1)

这样的事情怎么样?

/(?<=@).[^;]*/

它应匹配@和之间的所有内容; - 现在在http://www.rubular.com/处尝试过。

我也提醒不要在用户名中使用终止字符 - 很难区分@user ;;从提到@user;在一个句子后面跟一个分号。