Search code examples
htmljqueryparsingreplacehtml-parsing

Replace word starting with @ symbol with jQuery


I am trying to create a link when someone writes @NameHere, but with my actual code it doesn't work. The code does not read the $1 as the word placed after the @. It does if I place a whitespace after the code (like /^@(.*?)/ig ), but then it will read punctuations marks as part of the mentioned name. If left without the white space (/^@(.*?)/ig), it won't read the word.

I've been trying to fix but don't know how.

https://jsfiddle.net/ElenaMcDowell/pebjtwrz/79/

<div class="previewDocument-box">
    <h1>Preview</h1>
    <div class="previewDocument-text"></div>
</div>
<textarea id="ECEditor" class="editor-textarea" style="height: 200px;" name="editor-text"></textarea>

$('#ECEditor').on('input', function() {
     var text = $(this).val();
     var bb =  [
            /\[b\](.*?)\[\/b\]/ig,
        /^@(.*?)/ig
        
    ];
    
    var bb_html = [
            '<strong>$1</strong>',
        '<a class="MLPrev" href="profile?id=$1" target="_blank">@$1</a>&nbsp;'
    ];
 
    for (var i =0;i<bb.length;i++) {
      text = text.replace(bb[i], bb_html[i]);
    }
     $('.previewDocument-text').html(text);
  });

Solution

  • It seems what you actually need is the following:

    /@(\w+)(\b)/g
    

    This will match a sequence of "word" characters, followed by a "word boundary" (essentially a non-word character such as a space or punctuation, or the end of the line).

    The use of i is redundant, so I've removed it from the match.

    Note we also don't anchor the match to the start of the line, since that would not work if the tag appears mid-text.

    Your replacement would then become:

    '<a class="MLPrev" href="profile?id=$1" target="_blank">@$1</a>$2'
    

    (which is the same, except that instead of inserting a non-breaking space, we insert whatever character followed the tag - whether its a space or punctuation, or other "non-word" character).

    Here is a working snippet:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>Example</title>
    </head>
    <body>
    
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
      <div class="previewDocument-box">
        <h1>Preview</h1>
        <div class="previewDocument-text"></div>
      </div>
    
      <textarea id="ECEditor" class="editor-textarea" style="height: 200px;" name="editor-text"></textarea>
    
      <script type="text/javascript">
        $('#ECEditor').on('input', function() {
          let text = $(this).val();
          const bb = [
            /\[b\](.*?)\[\/b\]/g,
            /@(\w+)(\b)/g
          ];
    
          const bb_html = [
            '<strong>$1</strong>',
            '<a class="MLPrev" href="profile?id=$1" target="_blank">@$1</a>$2'
          ];
    
          for (let i = 0; i < bb.length; i++) {
            text = text.replace(bb[i], bb_html[i]);
          }
          $('.previewDocument-text').html(text);
        });
      </script>
    
    </body>
    </html>

    Also, this approach ensures that the tag is hyperlinked while typing, rather than forcing the user to insert something afterwards (such as a space or punctuation). Therefore, it would also work if the tag appeared at the end of the line.