JSFiddle - React, Tailwind, and code Playground

by DeathWalker

JavaScript

const createMap = (tokens) => {
  const map = {}
  tokens.forEach(function(val){
  	map[val] = true
  })
  return map
}

const handles = ["john", "johnathan", "sarah"]
const topics = ["home", "hometown"]
const handleMap = createMap(handles)
const topicMap = createMap(topics)
const input = "@john and @johnathan went to see @sarah in their #hometown to look at her new #home."
const expected = '<a href="/user/john">@john</a> and <a href="/user/johnathan">@johnathan</a> went to see <a href="/user/sarah">@sarah</a> in their <a href="/topics/hometown">#hometown</a> to look at her new <a href="/topics/home">#home</a>.'

const funcA = (input, handles, topics) => {
  return input
    .replace(new RegExp(`@([a-zA-Z0-9]+)\b`, 'g'), (match, handle) => handles.include(handle.toLowerCase()) ? `<a href="/user/${handle}">@${handle}</a>` : handle)
    .replace(new RegExp(`#([a-zA-Z0-9]+)\b`, 'g'), (match, topic) => topics.include(topic.toLowerCase()) ? `<a href="/user/${topic}">@${topic}</a>` : topic)
}

const funcC = (input, handles, topics) => {
  return input
    .replace(new RegExp(`@([a-zA-Z0-9]+)\b`, 'g'), (match, handle) => handleMap[handle.toLowerCase()] ? `<a href="/user/${handle}">@${handle}</a>` : handle)
    .replace(new RegExp(`#([a-zA-Z0-9]+)\b`, 'g'), (match, topic) => topicMap[topic.toLowerCase()] ? `<a href="/user/${topic}">@${topic}</a>` : topic)
}

const funcB = (input, handles, topics) => {
  return input.replace(
    new RegExp('@(' + handles.join('|') + ')\\b', 'gmi'), `<a href="/user/$1">@$1</a>`
  ).replace(
    new RegExp('#(' + topics.join('|') + ')\\b', 'gmi'), `<a href="/topics/$1">#$1</a>`
  );
}

console.log(funcA(input,handles,topics)==expected)
console.log(funcB(input,handles,topics)==expected)
console.log(funcC(input,handles,topics)==expected)