Substituindo todos os caracteres não alfanuméricos por cadeias vazias

197

Tentei usar isso, mas não funcionou.

return value.replaceAll("/[^A-Za-z0-9 ]/", "");
Alex Gomes
fonte
36
Pessoal, vocês esquecem que existem outros alfabetos além do latino.
Matev #
2
Mas se você deseja validar um nome de host, por exemplo, seria bom excluir alfabetos inválidos.
Gurnard

Respostas:

245

Use [^A-Za-z0-9].

Nota: removeu o espaço, pois isso normalmente não é considerado alfanumérico.

Mirek Pluta
fonte
10
Nem o espaço no final da classe de personagem.
31420 Andrew Duffy
6
Ele provavelmente está acostumado a programar em PHP.
William
10
@William - é lamentável que PHP está agora a obtenção de crédito para PCRE
Thomas Dignan
o reg exp está ok, basta remover "/" da string regexp de value.replaceAll ("/ [^ A-Za-z0-9] /", ""); para value.replaceAll ("[^ A-Za-z0-9]", ""); você não precisa do "/" dentro do regexp, acho que confundiu com os padrões javascript
eriknyk
128

Experimentar

return value.replaceAll("[^A-Za-z0-9]", "");

ou

return value.replaceAll("[\\W]|_", "");
Andrew Duffy
fonte
4
Com sublinhados,return value.replaceAll("\\W", "");
Erickson
Claro. Os compiladores são ótimos em identificar esse tipo de coisa.
22820 Andrew Duffy
1
O segundo não responde à pergunta. E quanto a caracteres como: / \ etc?
WW.
67

Você deve estar ciente de que [^a-zA-Z]substituirá os caracteres que não estão no intervalo de caracteres AZ / az. Isso significa que os caracteres especiais como é, ßetc, ou caracteres cirílicos e tal será removido.

Se a substituição desses caracteres não for desejada, use classes de caracteres predefinidas:

 str.replaceAll("[^\\p{IsAlphabetic}\\p{IsDigit}]", "");

PS: \p{Alnum}não alcança esse efeito, age da mesma forma que [A-Za-z0-9].

Andre Steingress
fonte
11
Muito obrigado por este post - foi muito útil para mim. Além disso, acredito que esta é a resposta real à pergunta. O alfabeto latino não é o único no mundo!
Mateva 15/10
2
Na verdade, o regex declarado tratará "^" como um caractere válido, pois apenas a primeira ocorrência de "^" está negando o significado da seleção. [^\\p{IsAlphabetic}\\p{IsDigit}]funciona bem.
Bogdan Klichuk 19/01/19
1
@JakubTurcovsky docs.oracle.com/javase/10/docs/api/java/util/regex/Pattern.html define IsAlphabetic e IsDigit como propriedades binárias. Alpha e Digit são classes de caracteres POSIX (somente US-ASCII). Exceto que o sinalizador docs.oracle.com/javase/10/docs/api/java/util/regex/… está especificado.
Andre Steingress
@AndreSteingress Correto, o motivo {IsDigit}não funciona para mim e {Digit}é que estou tentando fazer isso no Android. E o Android está UNICODE_CHARACTER_CLASSativado por padrão. Obrigado pela autorização.
Jakub Turcovsky
Como permitir apenas Alpha, Digit e Emoji?
Robert Goodrick
50
return value.replaceAll("[^A-Za-z0-9 ]", "");

Isso deixará os espaços intactos. Presumo que é isso que você quer. Caso contrário, remova o espaço da regex.

erickson
fonte
21

Você também pode tentar este regex mais simples:

 str = str.replaceAll("\\P{Alnum}", "");
saurav
fonte
2
Ou, preservando o espaço em branco:str.replaceAll("[^\\p{Alnum}\\s]", "")
Jonik
Or \\p{Alnum}\\p{Space}.
membersound
10

As expressões regulares do Java não exigem que você coloque uma barra ( /) ou qualquer outro delimitador em torno do regex, em oposição a outras linguagens como Perl, por exemplo.

abyx
fonte
8

Eu criei este método para criar nomes de arquivos:

public static String safeChar(String input)
{
    char[] allowed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_".toCharArray();
    char[] charArray = input.toString().toCharArray();
    StringBuilder result = new StringBuilder();
    for (char c : charArray)
    {
        for (char a : allowed)
        {
            if(c==a) result.append(a);
        }
    }
    return result.toString();
}
zneo
fonte
5
Esta é uma força bruta. Regex é o caminho a seguir com a situação do OP.
Michael Peterson
1
Você está certo, regex é melhor. Mas na época, regex e eu não nos saímos bem.
Zneo 12/04
Hah, alguém realmente se dá tão bem com regex? ;)
Michael Peterson
6

Solução:

value.replaceAll("[^A-Za-z0-9]", "")

Explicação:

[^abc] Quando um sinal de intercalação ^aparece como o primeiro caractere entre colchetes, ele nega o padrão. Esse padrão corresponde a qualquer caractere, exceto a ou b ou c.

Olhando para a palavra-chave como duas funções:

  • [(Pattern)] = match(Pattern)
  • [^(Pattern)] = notMatch(Pattern)

Além disso, em relação a um padrão:

  • A-Z = all characters included from A to Z

  • a-z = all characters included from a to z

  • 0=9 = all characters included from 0 to 9

Portanto, ele substituirá todo o char NÃO incluído no padrão

GalloCedrone
fonte
3

Se você também deseja permitir caracteres alfanuméricos que não pertencem ao conjunto de caracteres ascii, como, por exemplo, tremados alemães, considere usar a seguinte solução:

 String value = "your value";

 // this could be placed as a static final constant, so the compiling is only done once
 Pattern pattern = Pattern.compile("[^\\w]", Pattern.UNICODE_CHARACTER_CLASS);

 value = pattern.matcher(value).replaceAll("");

Observe que o uso do sinalizador UNICODE_CHARACTER_CLASS pode ter uma imposição à penalidade de desempenho (consulte o javadoc deste sinalizador)

estalar
fonte
1

Método simples:

public boolean isBlank(String value) {
    return (value == null || value.equals("") || value.equals("null") || value.trim().equals(""));
}

public String normalizeOnlyLettersNumbers(String str) {
    if (!isBlank(str)) {
        return str.replaceAll("[^\\p{L}\\p{Nd}]+", "");
    } else {
        return "";
    }
}
Alberto Cerqueira
fonte
1

Usando o Guava, você pode combinar facilmente diferentes tipos de critérios. Para sua solução específica, você pode usar:

value = CharMatcher.inRange('0', '9')
        .or(CharMatcher.inRange('a', 'z')
        .or(CharMatcher.inRange('A', 'Z'))).retainFrom(value)
Deb
fonte
1

O CharMatcher da Guava fornece uma solução concisa:

output = CharMatcher.javaLetterOrDigit().retainFrom(input);
Bunarro
fonte