Escreva um programa que leia uma sequência de n caracteres e imprima a sequência convertida para maiúscula, eliminando os caracteres que não forem letras ou números

Ola, sou novo aqui no fórum e bem novato na linguagem Java.
Estou com dificuldade de resolver essa questao utilizando lacos.
Consegui resolver ela pelo (str.replace.All), mas utilizando lacos nao fui capaz.

import java.util.*;
public class Desafio
{
   public static void main(String args[])
   {
       Scanner key= new Scanner (System.in);
       System.out.println("Digite uma sequencia de caracteres");
       String valor = key.next(); //sequencia de caracteres armazenada em " valor"
       
       String valorMaiusculo= valor.toUpperCase(); //transformar todas as letras para maiusculo e armazenar em "valorMaiusculo"
       //System.out.println(valorMaiusculo);
       String strApenasNum= RetornaNumeroseLetras(valorMaiusculo);//chamar metodo e armazenar na variavel "strApenasNum"
       System.out.println(strApenasNum);
    }
    
   public static String RetornaNumeroseLetras(String str)// metodo que recebe uma string e tem a funcao de retirar todos os caracteres que nao sao numeros e nem letras
   {
       if (str != null)//caso a string nao esteja vazia
       {
           return str.replaceAll("[^0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ]","");//usa-se o metodo replaceAll, no qual tem a funcao de "nomedastring.replaceAll(String a ser substituida ou mantido, string que substitui)
       }
       else
       {
           return "";
       }
   }
}

Alguem pode me dar uma luz por onde eu posso comecar?

Creio que o foco não seja laços, mas sim a regex é ela quem vai ser fundamental neste caso.
Procure material sobre regex no google, Ex.: regex java.
Recomendação: https://www.youtube.com/results?search_query=xti+regex

public static void main(String[] args) {
    System.out.println("Digite uma sequência de caracteres");
    System.out.println(repor(new Scanner(System.in).nextLine()));
}

private static String repor(String linha) {
    //No lugar da StringBuilder poderia ser uma string comum e dentro do if string+= linha.charAt(i)+"";
    StringBuilder retorno = new StringBuilder();
    for (int i = 0; i < linha.length(); i++) {
        if ((linha.charAt(i) + "").matches("\\w")) {// \\w filtra letras e números não aceitando os demais valores
            retorno.append(linha.charAt(i));
        }
    }
    return retorno.toString();
}