2009-10-23 24 views
61

Aparentemente, el sabor Regex de Java cuenta los diéresis y otros caracteres especiales como "caracteres de palabra" cuando utilizo Regex.Eliminar todos los "caracteres de palabra" no de una cadena en Java, dejando caracteres acentuados?

 "TESTÜTEST".replaceAll("\\W", "") 

devuelve "testtest" para mí. Lo que quiero es que solo se eliminen todos los "personajes de palabras" que realmente no sean "personajes de palabras". Cualquier forma de hacer esto sin tener algo en la línea de

  "[^A-Za-z0-9äöüÄÖÜßéèáàúùóò]" 

solo para realizar I forgot ô?

+0

Toda la referencia Unicode [http://www.regular-expressions.info/unicode.html](http://www.regular-expressions.info/unicode.html) – zaletniy

Respuesta

140

Uso [^\p{L}\p{Nd}]+ - esto coincide con todos los caracteres (Unicode) que no son letras ni dígitos (decimales).

En Java:

String resultString = subjectString.replaceAll("[^\\p{L}\\p{Nd}]+", ""); 

Editar:

he cambiado \p{N}-\p{Nd} ya que el primero también coincide con algunos símbolos numéricos como ¼; este último no. Véalo en regex101.com.

+1

¿Por qué '\\ [' dentro de tu clase de personaje? –

+1

Vaya. Error de tipografía. Corregido –

+2

funciona como un encanto! ¡Gracias! – Epaga

2

Bueno, aquí es una solución que terminó con, pero espero que hay una más elegante ... uno

StringBuilder result = new StringBuilder(); 
for(int i=0; i<name.length(); i++) { 
    char tmpChar = name.charAt(i); 
    if (Character.isLetterOrDigit(tmpChar) || tmpChar == '_') { 
     result.append(tmpChar); 
    } 
} 

result termina con el resultado deseado ...

+1

El hecho de que su variable String se llama 'name' y sugiere que no será una cadena grande. Pero en los casos en que se vuelve grande (un par de miles de caracteres), iría con el enunciado for como lo hacía ahora. –

5

Por momentos no desea simplemente eliminar los caracteres, sino simplemente eliminar los acentos. Se me ocurrió la siguiente clase de utilidad que utilizo en mis proyectos web Java REST cada vez que necesito para incluir una cadena en una dirección URL:

import java.text.Normalizer; 
import java.text.Normalizer.Form; 

import org.apache.commons.lang.StringUtils; 

/** 
* Utility class for String manipulation. 
* 
* @author Stefan Haberl 
*/ 
public abstract class TextUtils { 
    private static String[] searchList = { "Ä", "ä", "Ö", "ö", "Ü", "ü", "ß" }; 
    private static String[] replaceList = { "Ae", "ae", "Oe", "oe", "Ue", "ue", 
      "sz" }; 

    /** 
    * Normalizes a String by removing all accents to original 127 US-ASCII 
    * characters. This method handles German umlauts and "sharp-s" correctly 
    * 
    * @param s 
    *   The String to normalize 
    * @return The normalized String 
    */ 
    public static String normalize(String s) { 
     if (s == null) 
      return null; 

     String n = null; 

     n = StringUtils.replaceEachRepeatedly(s, searchList, replaceList); 
     n = Normalizer.normalize(n, Form.NFD).replaceAll("[^\\p{ASCII}]", ""); 

     return n; 
    } 

    /** 
    * Returns a clean representation of a String which might be used safely 
    * within an URL. Slugs are a more human friendly form of URL encoding a 
    * String. 
    * <p> 
    * The method first normalizes a String, then converts it to lowercase and 
    * removes ASCII characters, which might be problematic in URLs: 
    * <ul> 
    * <li>all whitespaces 
    * <li>dots ('.') 
    * <li>(semi-)colons (';' and ':') 
    * <li>equals ('=') 
    * <li>ampersands ('&') 
    * <li>slashes ('/') 
    * <li>angle brackets ('<' and '>') 
    * </ul> 
    * 
    * @param s 
    *   The String to slugify 
    * @return The slugified String 
    * @see #normalize(String) 
    */ 
    public static String slugify(String s) { 

     if (s == null) 
      return null; 

     String n = normalize(s); 
     n = StringUtils.lowerCase(n); 
     n = n.replaceAll("[\\s.:;&=<>/]", ""); 

     return n; 
    } 
} 

Siendo un alemán que he incluido el manejo adecuado de las diéresis alemanas, así - la lista debería ser fácil de extender para otros idiomas.

HTH

EDIT: Nota que puede ser peligroso para incluir la cadena devuelta en una URL. Al menos debe codificar HTML para evitar ataques XSS.

+0

información importante sobre esto, puede obtener la clase/paquete StringUtils, etc. @ http://commons.apache.org/lang/download_lang.cgi – cV2

0

Puede consultar remove the accents and diacritic signs first, luego en cada posición de carácter compruebe si la cadena "simplificada" es una letra ascii - si lo es, la posición original debe contener caracteres de palabra, si no, puede eliminarse.

+0

La clase java.text.Normalizer no es compatible con el API de Android nivel 9, por lo que si su aplicación debe ser compatible con el nivel 8 de API (13% del total de dispositivos, de acuerdo con el panel de Android de Google), este método no es viable –

7

Estaba tratando de lograr exactamente lo contrario cuando tropecé con este hilo. Sé que es bastante viejo, pero esta es mi solución, no obstante. Puede usar bloques, consulte here. En este caso, compilar el código siguiente (con las importaciones derecha):

> String s = "äêìóblah"; 
> Pattern p = Pattern.compile("[\\p{InLatin-1Supplement}]+"); // this regex uses a block 
> Matcher m = p.matcher(s); 
> System.out.println(m.find()); 
> System.out.println(s.replaceAll(p.pattern(), "#")); 

debería ver el siguiente resultado:

cierto

#blah

Mejor ,

-4

Puedes usar StringUtils de apache

+1

Supongo que un poco más de información sería útil ... esto no es realmente una respuesta. – Micha

+0

por favor agregue algunos ejemplos de código. – Saurabh

Cuestiones relacionadas