Reemplazar todos los caracteres no alfanuméricos con cadenas vacías

197

Intenté usar esto pero no funcionó

return value.replaceAll("/[^A-Za-z0-9 ]/", "");
Alex Gomes
fuente
36
Chicos, se les olvida que hay otros alfabetos además del latino.
Mateva
2
Pero si desea validar un nombre de host, por ejemplo, sería bueno excluir alfabetos no válidos.
Gurnard

Respuestas:

245

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

Nota: se eliminó el espacio, ya que eso no suele considerarse alfanumérico.

Mirek Pluta
fuente
10
Tampoco el espacio al final de la clase de personaje.
Andrew Duffy el
66
Probablemente esté acostumbrado a programar en PHP.
William
10
@William: es lamentable que PHP ahora esté recibiendo crédito por PCRE
Thomas Dignan
el reg exp está bien, simplemente elimine "/" de la cadena regexp de value.replaceAll ("/ [^ A-Za-z0-9] /", ""); a value.replaceAll ("[^ A-Za-z0-9]", ""); no necesita el "/" dentro de la
expresión regular
128

Tratar

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

o

return value.replaceAll("[\\W]|_", "");
Andrew Duffy
fuente
44
Con guiones bajos,return value.replaceAll("\\W", "");
erickson
Por supuesto. Los compiladores son excelentes para detectar ese tipo de cosas.
Andrew Duffy el
1
El segundo no responde la pregunta. ¿Qué pasa con personajes como: / \ etc?
WW.
67

Debe tener en cuenta que [^a-zA-Z]reemplazará los caracteres que no se encuentren en el rango de caracteres AZ / az. Eso significa caracteres especiales como é, ßetc. o caracteres cirílicos y tales serán eliminados.

Si no se desea reemplazar estos caracteres, utilice clases de caracteres predefinidas en su lugar:

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

PD: \p{Alnum}no logra este efecto, actúa igual que [A-Za-z0-9].

Andre Steingress
fuente
11
Muchas gracias por esta publicación, fue muy útil para mí. Además, creo que esta es la respuesta real a la pregunta. ¡El alfabeto latino no es el único en el mundo!
Mateva
2
En realidad, la expresión regular indicada tratará "^" como un carácter válido, ya que solo la primera aparición de "^" niega el significado de la selección. [^\\p{IsAlphabetic}\\p{IsDigit}]funciona bien.
Bogdan Klichuk
1
@JakubTurcovsky docs.oracle.com/javase/10/docs/api/java/util/regex/Pattern.html define IsAlphabetic e IsDigit como propiedades binarias. Alpha y Digit son clases de caracteres POSIX (solo US-ASCII). Excepto que se especifica el indicador docs.oracle.com/javase/10/docs/api/java/util/regex/… .
Andre Steingress
@AndreSteingress Correcto, la razón {IsDigit}no funciona para mí y lo {Digit}hace es que estoy probando esto en Android. Y Android se ha UNICODE_CHARACTER_CLASSactivado de forma predeterminada. Gracias por el despacho.
Jakub Turcovsky
¿Cómo permitir solo Alpha, Digit y Emoji?
Robert Goodrick
50
return value.replaceAll("[^A-Za-z0-9 ]", "");

Esto dejará espacios intactos. Supongo que eso es lo que quieres. De lo contrario, elimine el espacio de la expresión regular.

erickson
fuente
21

También puedes probar esta expresión regular más simple:

 str = str.replaceAll("\\P{Alnum}", "");
saurav
fuente
2
O, preservando el espacio en blanco:str.replaceAll("[^\\p{Alnum}\\s]", "")
Jonik
O \\p{Alnum}\\p{Space}.
membersound
10

Las expresiones regulares de Java no requieren que coloque una barra diagonal ( /) o cualquier otro delimitador alrededor de la expresión regular, a diferencia de otros lenguajes como Perl, por ejemplo.

abyx
fuente
8

Hice este método para crear nombres de archivo:

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
fuente
55
Esto es bastante fuerza bruta. Regex es el camino a seguir con la situación del OP.
Michael Peterson
1
Tienes razón, regex es mejor. Pero en ese momento, regex y yo no llegué bien.
zneo
Hah, ¿alguien realmente se lleva tan bien con regex? ;)
Michael Peterson el
6

Solución:

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

Explicación:

[^abc] Cuando un cursor ^aparece como el primer carácter entre corchetes, niega el patrón. Este patrón coincide con cualquier carácter excepto a o b o c.

Mirando la palabra clave como dos funciones:

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

Además con respecto a un patrón:

  • 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

Por lo tanto, sustituirá todos los caracteres NO incluidos en el patrón

GalloCedrone
fuente
3

Si desea permitir también caracteres alfanuméricos que no pertenecen al conjunto de caracteres ascii, como por ejemplo, diéresis alemana, puede considerar usar la siguiente solución:

 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("");

Tenga en cuenta que el uso del indicador UNICODE_CHARACTER_CLASS podría imponer una penalización de rendimiento (consulte javadoc de este indicador)

chasquido
fuente
1

Método simple:

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
fuente
1

Usando Guava puedes combinar fácilmente diferentes tipos de criterios. Para su solución específica puede usar:

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

CharMatcher de Guava proporciona una solución concisa:

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