user2706191
user2706191

Reputation: 353

Regexp expression /(\@)(.*?)(\;)/ failing at quotations

I have a helper method that goes through any given block of text and replaces substrings that are in the format '@something;' with a link. It works with all test cases I've tried, including

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

but gets hung up on quotations, as in

@I'll fight you;

but still matches up until that point? Below, for hacky debugging purposes, I have the helper method putting three asterisks ('*') on either side of the assumed match, so the above tag results in

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

I can't figure it out.

(And if anyone has any additional tips and tricks on how to get it to match a tag like '@username;;', where the end character is also a part of the name, lemme know. I figured that might be too complicated and better done programmatically.)

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

Edit: I called a quotation mark a comma. I hate myself.

Upvotes: 0

Views: 34

Answers (1)

Jared
Jared

Reputation: 582

What about something like this?

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

it should match everything in between the @ and the ; -- as tried now at http://www.rubular.com/.

I'd also caution against using the termination character within the username -- it will be difficult to differentiate @user;; from maybe mentioning @user; in a sentence that is followed by a semi-colon.

Upvotes: 1

Related Questions