Tengo la siguiente función:

function formattedTitle(posttitle,hreflink) {
  return `<a href='`+ hreflink +`'>` + posttitle.replace(/(^|\s)(#[-.\w]+)/gi, `$1</a><a class="hashtag" href='/search?q=hashtag:"$2"'>$2</a><a href='`+ hreflink + `'>`) + '</a>';
}

Cuando corro

console.log(formattedTitle('This is #awesome news','google.com'));

Emite:

<a href='google.com'>This is </a><a class="hashtag" href='/search?q=hashtag:"#awesome"'>#awesome</a><a href='google.com'> news</a>
function formattedTitle(posttitle, hreflink) {
  return `<a href='` + hreflink + `'>` + posttitle.replace(/(^|\s)(#[-.\w]+)/gi, `$1</a><a class="hashtag" href='/search?q=hashtag:"$2"'>$2</a><a href='` + hreflink + `'>`) + '</a>';
}


console.log(formattedTitle('This is #awesome news', 'google.com'));

Observe cómo incluye el "#" en la coincidencia de $ 2. ¿Cómo puedo excluir el carácter hashtag en el atributo hashtag: pero mantenerlo entre el valor href?

Entonces la salida debería verse así:

<a href='google.com'>This is </a><a class="hashtag" href='/search?q=hashtag:"awesome"'>#awesome</a><a href='google.com'> news</a>

He podido hacer que funcione haciendo otro reemplazo en todo para reemplazar '/search?q=hashtag:"# con '/search?q=hashtag:", pero me pregunto si es posible sin el segundo reemplazo.

2
Pranoy C 28 oct. 2019 a las 05:46

3 respuestas

La mejor respuesta

Mueva el # fuera del segundo grupo capturado, para que no se capture. Al reemplazar, en href, reemplace con solo $2 (para que no haya hashtag). Al reemplazar el texto dentro el <a>, reemplácelo con #$2, para que el hashtag se agregue en el lugar correcto:

function formattedTitle(posttitle, hreflink) {
  return `<a href='` + hreflink + `'>`
    + posttitle.replace(/(^|\s)#([-.\w]+)/gi, `$1</a><a class="hashtag" href='/search?q=hashtag:"$2"'>#$2</a><a href='` + hreflink + `'>`)
    + '</a>';
}

console.log(formattedTitle('This is #awesome news', 'google.com'));
2
CertainPerformance 28 oct. 2019 a las 02:52

Solo necesita mover el símbolo hash fuera de su grupo de captura; hacerlo no cambiará la semántica correspondiente. Al igual que:

function formattedTitle(posttitle, hreflink) {
  return `<a href='`+ hreflink +`'>` + posttitle.replace(/(^|\s)#([-.\w]+)/gi, `$1</a><a class="hashtag" href='/search?q=hashtag:"$2"'>$2</a><a href='`+ hreflink + `'>`) + '</a>';
}
1
Michael Horn 28 oct. 2019 a las 02:53

Simplemente agregue otro grupo de captura para obtener una coincidencia con el hashtag (o cualquier otro personaje que desee capturar) en $2 y otra coincidencia sin el hashtag en $3: (#([-.\w]+)) en lugar de (#[-.\w]+):

function formattedTitle(postTitle, href) {
  const parts = postTitle.replace(
    /(^|\s)(#([-.\w]+))/gi,
    `$1</a><a class="hashtag" href="/search?q=hashtag:$3">$2</a><a href="${ href }">`);
  
  return `<a href="${ href }">${ parts }</a>`;
}

document.getElementById('postTitle').innerHTML = formattedTitle('This is #awesome news', 'https://google.com');
h3 {
  font-family: monospace;
  font-size: 24px;
  margin: 8px 0;
}

a {
  padding: 8px 0;
  text-decoration: none;
  display: inline-block;
}

.hashtag {
  padding: 6px 8px;
  border: 3px solid blue;
  border-radius: 3px;
  margin: 0 8px;
}
<h3 id="postTitle"></h3>
0
Danziger 28 oct. 2019 a las 03:06