Che cos'è questo personaggio: '*'?


48

Un amico ha incollato un comando in una chat room di Slack che conteneva il personaggio *. Sembra normale *ma non lo è:

$ uniprops '*​'
uniprops: no character named ‹*​›

Se corro unipropssull'asterisco quando scrivo sulla mia macchina, ottengo:

$ uniprops '*'
U+002A ‹*› \N{ASTERISK}
    \pP \p{Po}
    All Any ASCII Assigned Basic_Latin Punct Is_Punctuation Common Zyyy Po P
       Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Other_Punctuation
       Pat_Syn Pattern_Syntax PatSyn POSIX_Graph POSIX_Print POSIX_Punct Print
       X_POSIX_Print Punctuation Unicode X_POSIX_Punct

Posso anche vedere che non è un vero asterisco passando attraverso od:

$ printf '*​' | od -c
0000000   * 342 200 213
0000004

Mentre quello normale dà:

$ printf '*' | od -c
0000000   *
0000001

Ecco il personaggio misterioso un po 'più grande:

*

E l'asterisco normale (sì, sembrano identici):

*

Quindi, unipropsnon so cosa sia e non riesco a trovarlo su http://www.fileformat.info/ . So che l'amico che l'ha incollato è su OS X (io sono su Linux) e che funziona sul loro sistema come un normale asterisco. Suppongo che Slack l'abbia in qualche modo cambiato. Quindi, qualcuno ha idea di cosa sia quel personaggio?

Nota che non puoi copiare lo strano personaggio direttamente dalla domanda. Apparentemente, il motore Stack Exchange rimuove i caratteri non stampabili finali. Fai clic sul link "modifica" e copia da lì invece.


unipropsè un piccolo script pulito incluso nel Unicode::Tusslemodulo Perl che identifica e stampa informazioni sul personaggio che gli dai.


Impossibile riprodurre. Ho usato ord("*")per la stringa incollata e la *chiave nativa e ho ottenuto lo stesso numero per entrambi (42).
Marzo Ho

7
@March. Accidenti, sembra che il motore SE lo stia mangiando. Ho provato prima di pubblicare e ho potuto copiare lo strano personaggio (anche se sto cominciando a capire che il problema è che ci sono stati aggiunti altri caratteri non stampabili) ma non riesco nemmeno a copiare dalla domanda pubblicata. Devi fare clic sul collegamento modifica e copiarlo da lì.
terdon,

2
Stranamente, sull'app Android, lo zero con spazio viene visualizzato come se fosse uno spazio normale.
derobert,

1
È interessante notare che quando incollo da "modifica" nel mio terminale urxvt, è già visualizzato come *<200b>.
bodo,

Se lo copi dalla sezione del tuo codice, ad esempio la riga di uniprops, copia OK senza dover andare alla fonte della domanda. (Incollandolo anche nell'interprete Python3 '*\u200b')
TessellatingHeckler

Risposte:


71

L'incolla non è riuscita a causa dell'asterisco, che è un asterisco perfettamente regolare, ma a causa del carattere Unicode U + 200B . Poiché il personaggio è a ZERO WIDTH SPACE, non viene visualizzato quando viene copiato.

Utilizzando il codice Python:

stro=u"'*​'?"
def uniconv(text):
    return " ".join(hex(ord(char)) for char in text)
uniconv(stro)

La funzione uniconvconverte la stringa di input (in questo caso u"'*'?") nei loro equivalenti di tabella codici Unicode in formato esadecimale. Il uprefisso alla stringa identifica la stringa come stringa Unicode.

Sono stato in grado di ottenere l'output:

0x27 0x2a 0x200b 0x27 0x3f

Possiamo chiaramente vedere che 0x27, 0x2ae 0x3fsono i valori ASCII / Unicode esadecimali per i personaggi ', *e ?rispettivamente. Ciò lascia 0x200b, quindi identificando il personaggio.

Nota che il codice Python, una volta incollato nel corpo, aveva il carattere U + 200B rimosso dal software Markdown di SE. Per ottenere il risultato atteso, è necessario copiarlo direttamente dal titolo utilizzando la vista Modifica.


5
La sostituzione strcon hexprodurrà i punti di codice in esadecimali, rendendoli più facili da riconoscere o cercare.
deltab,

C'è anche un modulo Python dedicato chiamato unicodedata, con il quale puoi interrogare i nomi dei personaggi, la categoria ecc.
bodo

4
I caratteri ZERO WIDTH SPACE e ZERO WIDTH JOINER sono utili da utilizzare con i sistemi di commento che tentano di bloccare i termini spam comuni. Ad esempio, per sottolineare che Bernie Sanders è stato eletto al Senato come socialista (senza far scattare una trappola di spam per "Cialis"), scriverlo come "Soci & zwj; alist" se le entità HTML sono rispettate o incollare il carattere dalla Mappa caratteri o equivalente se non lo sono.
Monty Harder,

27

Con l'aiuto di @Rinzwind nella chat room di Ask Ubuntu, ho capito che il problema non è affatto il personaggio. Nota l'output di od:

$ printf '*​' | od -c
0000000   * 342 200 213
0000004

Il 342 200 213è una rappresentazione ottale di un altro personaggio e possiamo usare questo sito per guardare in su:

Character                   ​               
Character name                              ZERO WIDTH SPACE
Hex code point                              200B
Decimal code point                          8203
Hex UTF-8 bytes                             E2 80 8B
Octal UTF-8 bytes                           342 200 213
UTF-8 bytes as Latin-1 characters bytes     â <80> <8B>

Quindi, quello che avevo in realtà erano due caratteri unicode, lo *spazio normale e uno zero.


6
Un altro modo per farlo è printf '\342\200\213' | uniname. (uniname proviene dal pacchetto uniutils.)
deltab,

1
Da questo sito puoi avere conversioni di formato diverso: per HEX dà 002A 200B, per utf-8 2A E2 80 8Bper utf-16 002A 200B...
Hastur
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.