Rimozione corsivo da caratteri in una stringa

di il
4 risposte

Rimozione corsivo da caratteri in una stringa

Ciao a tutti,
ho delle stringhe che contengono alcune lettere in corsivo (Mathematical Italic Small) e vorrei "ripulirle", ovvero rimpiazzare ogni lettera corsiva con la sua controparte non corsiva.
Le lettere corsive sono rappresentate come segue:

a : \uD835\uDC4E
...
z : \uD835\uDC67


La prima cosa che mi viene in mente è estrarre l'ultimo byte e sottrarre la differenza che c'è con i corrispettivi caratteri nella rappresentazione ascii. Non riesco a capire però come convertire questo tipo di carattere in byte o un altro formato comodo per la conversione. Potreste darmi una mano?

4 Risposte

  • Re: Rimozione corsivo da caratteri in una stringa

    Aleph Zero ha scritto:


    
    a : \uD835\uDC4E
    ...
    z : \uD835\uDC67
    
    Innanzitutto sono 2 char per ciascuno di quei caratteri perché quelli sono i cosiddetti "surrogate pairs". Lo standard Unicode contempla molto più che 65536 caratteri. Per rappresentare in UTF-16 quei caratteri oltre 65535 hanno inventato questa codifica per cui appunto servono 2 caratteri a 16 bit (il char di Java).

    Comunque la conversione si può fare sicuramente in svariati modi. Tra questi anche sicuramente con l'uso ("furbo") delle espressioni regolari.
    Banalmente anche andando a cercare nella stringa gli \uD835 e verificare se il char successivo è tra \uDC4E e \uDC67 .

    EDIT: se puoi usare almeno Java 9, c'è il bel replaceAll?(Function<MatchResult,String> replacer) di Matcher che è stato introdotto.
    Se fai un Pattern in cui c'è una "classe di caratteri" tra due code-point, poi puoi banalmente rimpiazzare il surrogate pair con il carattere a-z corrispondente.

    Vedi qui il Mathematical Italic Small A:
  • Re: Rimozione corsivo da caratteri in una stringa

    Grazie mille Andbin. Con i tuoi consigli mi hai indirizzato sulla strada giusta.
    Dalla documentazione ho trovato che una surrugate pair (non sapevo che si chiamasse così grazie ) ha comunque un unico codepoint , ovvero quello che serviva a me per la conversione. Ho quindi fatto un replace sul range dei caratteri che mi servivano, sostituendoli con la loro versione decrementata della differenza con i caratteri non corsivi.
    se puoi usare almeno Java 9
    In realtà sto usando Clojure. È una sorta di Java funzionale e usano le stesse librerie.

    Giusto per correttezza posto la soluzione.
    
    
    (def ^:const ITALIC_DIFF 119789)
    
    (defn clean-italic [italic-char]
      (let [codepoint (. italic-char codePointAt 0)] // trovo il codepoint del carettere corsivo
        (-> codepoint (- ITALIC_DIFF) char str))) //al codepoint sottraggo la differenza, lo converto prima in char e poi in stringa 
    
    (defn foo []
      (let [cmml // genero la stringa
            cmml-no-italic (str/replace cmml #"[\uD835\uDC4E-\uD835\uDC67]+" #(clean-italic %1))]
        cmml-no-italic)
      )
    
    
  • Re: Rimozione corsivo da caratteri in una stringa

    Aleph Zero ha scritto:


    In realtà sto usando Clojure.
    Ah ok. Per me la sintassi di Clojure è "quasi arabo", come si dice.

    Comunque quello che pensavo per Java 9 è (scritto al volo ma provato, funziona):
    String str = "Dalla \uD835\uDC4E alla \uD835\uDC67";
    
    Pattern p = Pattern.compile("[\\x{1D44E}-\\x{1D467}]");
    Matcher m = p.matcher(str);
    
    String res = m.replaceAll(mr -> String.valueOf((char) (mr.group().charAt(1) - 0xDBED)));
  • Re: Rimozione corsivo da caratteri in una stringa

    Per me la sintassi di Clojure è "quasi arabo"
    All'inizio sembra strana ma dopo un po' ci si abitua .

    La tua soluzione mi piace parecchio, è semplice e compatta. La parte funzionale di Java è una manna dal cielo.

    Comunque ti ringrazio ancora per l'aiuto
Devi accedere o registrarti per scrivere nel forum
4 risposte