Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] Encontrar as hashtags por regex

Gostaria de saber, neste caso, se o código que eu fiz, por mais simples que esteja, condiz com o desafio "Extraindo hashtags de um texto". Diferente do código do instrutor, eu fiz com que ele simplesmente iterasse sobre a minha String e, caso encontrasse alguma hashtag, ele a exibisse; caso contrário, não faria nada.

Meu codigo ficou assim:

package com.github.rickmvi.challenge15;

import com.github.rickmvi.jtoolbox.console.Out;
import com.github.rickmvi.jtoolbox.console.utils.ScannerUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Hashtagstarget {
    public static void main(String[] args) {
        ScannerUtils.init();

        final Pattern PATTERN = Pattern.compile("#[a-zA-Z]+"); // exemplo 1
        final Pattern PATTERN2 = Pattern.compile("#\\w+"); // exemplo 2

        Out.print("Enter a react: ");
        String react = ScannerUtils.nextLine();

        Matcher matcher = PATTERN2.matcher(react);

        for (int i = 0; i < react.length(); i++) {
            if (matcher.find())
                Out.printFormatted(
                        "The react [{}] is a hashtag%n",
                        react.substring(
                                matcher.start(),
                                matcher.end())
                );
        }

        ScannerUtils.close();
    }
}

Eu também cheguei a fazer uma pequena refatoração no código do instrutor.

package com.github.rickmvi.challenge15;

import com.github.rickmvi.jtoolbox.console.Out;
import com.github.rickmvi.jtoolbox.console.utils.ScannerUtils;
import com.github.rickmvi.jtoolbox.control.While;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExtraindoHashtags {
    public static void main(String[] args) {
        ScannerUtils.init();

        System.out.print("Digite o texto: ");
        String texto = ScannerUtils.nextLine();

        Pattern pattern = Pattern.compile("#\\w+");
        Matcher matcher = pattern.matcher(texto);

        ArrayList<String> hashtags = new ArrayList<>();

        While.whileTrue(matcher::find, () -> hashtags.add(matcher.group()));

        ScannerUtils.close();
        Out.printLine(hashtags.isEmpty() ?
                "Nenhuma hashtag encontrada." :
                "Hashtags encontradas: " + String.join(", ", hashtags)
        );
    }
}

O que meu método whiletrue faz:

@lombok.experimental.UtilityClass
public class While {
    /**
     * Repeatedly executes the action while the condition returns true.
     *
     * @param condition the condition to evaluate before each iteration
     * @param action    the action to execute
     */
    public static void whileTrue(@NotNull BooleanSupplier condition, Runnable action) {
        while (condition.getAsBoolean()) action.run();
    }

A parte do Scanner, eu transformei em uma classe utilitária para evitar ter que instanciá-la manualmente sempre. Então, em todo projeto que faço, apenas a chamo.
Insira aqui a descrição dessa imagem para ajudar na acessibilidade

O método printFormatted foi feito usando regex; ele substitui alguns placeholders definidos por objetos, como o printf faz.
Insira aqui a descrição dessa imagem para ajudar na acessibilidade
Insira aqui a descrição dessa imagem para ajudar na acessibilidade
Insira aqui a descrição dessa imagem para ajudar na acessibilidade
Insira aqui a descrição dessa imagem para ajudar na acessibilidade

2 respostas
solução!

Olá Rick! Como vai?

Seu código está bem estruturado e atende ao desafio de extrair hashtags de um texto. A abordagem que você usou, utilizando Pattern e Matcher, é eficiente para encontrar padrões de hashtags. Vamos analisar alguns pontos:

  1. Regex: Você usou #[a-zA-Z]+ e #\\w+. Ambas as regex são adequadas, mas #\\w+ é mais abrangente, pois inclui números e underscores, além de letras.

  2. Iteração: No seu primeiro exemplo, você está iterando sobre o comprimento da string, mas o matcher.find() já cuida de encontrar todas as ocorrências no texto. Não é necessário iterar manualmente sobre os caracteres da string.

  3. Uso de While: A refatoração usando o método whileTrue é uma boa prática para tornar o código mais legível e modular.

  4. Saída: No segundo exemplo, você armazena as hashtags em uma lista e depois as imprime, o que facilita a manipulação e apresentação dos dados.

Aqui está uma sugestão de como simplificar o primeiro exemplo:

Matcher matcher = PATTERN2.matcher(react);
while (matcher.find()) {
    Out.printFormatted(
            "The react [{}] is a hashtag%n",
            matcher.group()
    );
}

Dessa forma, você elimina a necessidade do loop for e utiliza apenas o matcher.find() para iterar sobre as hashtags.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Obrigado pela dica.