2009-10-23 23 views
61

Apparentemente l'aroma di Regex di Java conta gli Umlaut e altri caratteri speciali come non "caratteri word" quando utilizzo Regex.Rimuovere tutti i "caratteri word" non da una stringa in Java, lasciando caratteri accentati?

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

restituisce "TESTTEST" per me. Quello che voglio è che solo tutti i veri "caratteri" non vengano rimossi. Qualsiasi modo per fare questo senza avere qualcosa sulla falsariga di

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

solo per rendersi conto di aver dimenticato ô?

+0

L'intero riferimento Unicode [http://www.regular-expressions.info/unicode.html](http://www.regular-expressions.info/unicode.html) – zaletniy

risposta

140

Usa [^\p{L}\p{Nd}]+ - questo corrisponde a tutti i caratteri (Unicode) che non sono né lettere né cifre (decimali).

In Java:

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

Edit:

ho cambiato \p{N}-\p{Nd} perché il primo corrisponde anche alcuni simboli numerici come ¼; il secondo no. Guardalo su regex101.com.

+1

Perché il '\\ [' nella classe del tuo personaggio? –

+1

Oops. Errore di battitura. Corretto. –

+2

funziona come un fascino! Grazie! – Epaga

2

Bene, qui è una soluzione che ho finito con, ma spero ci sia una più elegante ...

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 finisce con il risultato desiderato ...

+1

Il fatto che la variabile String si chiama 'name' suggerisce che non sarà una grande stringa. Ma nei casi in cui diventa grande (un paio di migliaia di caratteri), andrei con la dichiarazione for-like come hai fatto ora. –

5

A volte non si desidera semplicemente rimuovere i caratteri, ma basta rimuovere gli accenti. Sono venuto con la seguente classe di utilità che uso nei miei progetti web Java REST ogni volta che ho bisogno di includere una stringa in un 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; 
    } 
} 

Essendo un altoparlante tedesco Ho incluso corretta gestione dei dieresi tedesche, nonché - l'elenco dovrebbe essere facile da estendere per altre lingue.

HTH

EDIT: Nota che può essere pericoloso per includere la stringa restituita in un URL. Dovresti almeno codificarlo in HTML per prevenire gli attacchi XSS.

+0

informazioni importanti su questo, puoi ottenere la classe/pacchetto StringUtils ecc. @ Http://commons.apache.org/lang/download_lang.cgi – cV2

0

Si potrebbe voler remove the accents and diacritic signs first, quindi su ogni posizione di carattere controllare se la stringa "semplificata" è una lettera ascii - se lo è, la posizione originale deve contenere caratteri di parola, in caso contrario, può essere rimosso.

+0

Classe java.text.Normalizer non è supportata prima del livello API di Android 9, quindi se la tua app deve essere compatibile con il livello API 8 (13% dei dispositivi totali, secondo la dashboard Android di Google), questo metodo non è valido –

7

Stavo cercando di ottenere l'esatto opposto quando ho urtato questo thread. So che è piuttosto vecchio, ma comunque ecco la mia soluzione. È possibile utilizzare i blocchi, vedere here. In questo caso, compilare il seguente codice (con le importazioni a destra):

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

si dovrebbe vedere il seguente output:

vero

#blah

migliore ,

-4

È possibile utilizzare StringUtils da apache

+1

Immagino che un po 'più di informazioni sarebbero utili ... questa non è proprio una risposta. – Micha

+0

per favore aggiungi alcuni esempi di codice. – Saurabh

Problemi correlati