Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

115
Visualizações
Regex match hashtag with exceptions

I have the current expression:

/(?<![http://|https://|#])#([\d\w]+[^\d\s<]+[^\s<>]+)/g

However it's not compatible to run on Safari. I'm trying to handle the following cases:

#tag => match
#123 => no match
#32bit => match
##tag => no match
http://google.com/#/test => no match
tag##tag => no match
tag#tag => no match
<p>#tag</p> => match only #tag
#tag. => match only #tag
tag## => no match
tag# => no match
this is a match #tag => only #tag 

I wonder how I can make a character before the match result in a negative match. E.g. # and /.

Is there any alternative to negative look behind that is compatible with Safari?

Thanks in advance.

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You might use a negated character class and a capture group, and make sure that there are not only digits.

Note that \w also matches \d

(?:^|[^\w#/])(#(?!\d+\b)\w+)\b

Explanation

  • (?: Non capture group
    • ^ Assert the start of the string
    • | Or
    • [^\w#/] Match a single non word char other than # or /
  • ) Close non capture group
  • ( Capture group 1
    • # Match literally
    • (?!\d+\b) Negative lookahead, assert not only digits to the right followed by a word boundary
    • \w+ Match 1+ word characters
  • ) Close group 1
  • \b A word boundary to prevent a partial word match

Regex demo

let regex = /(?:^|[^\w#/])(#(?!\d+\b)\w+)\b/;
[
  "#tag",
  "#123",
  "#32bit",
  "##tag",
  "http://google.com/#/test",
  "tag##tag",
  "tag#tag",
  "<p>#tag</p>",
  "#tag.",
  "tag##",
  "tag#"
].forEach(s => {
  const m = s.match(regex)
  if (m) {
    console.log(`${s} --> ${m[1]}`)
  }
})

Using the matches in a replacement:

let regex = /((?:^|[^\w#/]))(#(?!\d+\b)\w+)\b/;
[
  "#tag",
  "#123",
  "#32bit",
  "##tag",
  "http://google.com/#/test",
  "tag##tag",
  "tag#tag",
  "<p>#tag</p>",
  "#tag.",
  "tag##",
  "tag#",
  "this is a match #tag"
].forEach(s => {
  const m = s.match(regex)
  if (m) {
    console.log(s.replace(regex, "$1<span>$2</span>"))
  }
})

about 4 years ago · Santiago Trujillo Relatório

0

This satisfies your test cases. Not sure though whether you want this or not.

It does't work on #123 but I forgot it and I'm now lazy to add it as a screenshot.

/^(?:[^#]*[^#\w])?(#[\w]*[a-zA-Z][\w]*).*$/g

If you only want to allow <tags> before the "#", you can insted use @kendle's solution for the first non-capture group (before the actual group starting with #).

(?:<\w*>)?

enter image description here

about 4 years ago · Santiago Trujillo Relatório

0

If you use the following pattern the second matching group contains what you want.

^(<\w*>)?(#\w+[a-zA-Z])
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda