with - using popen python




Genera una stringa UTF-8 casuale in Python (6)

Mi piacerebbe testare la gestione Unicode del mio codice. C'è qualcosa che posso inserire in casual.choice () per selezionare dall'intero range Unicode, preferibilmente non un modulo esterno? Né Google né StackOverflow sembrano avere una risposta.

Modifica: Sembra che questo sia più complesso del previsto, quindi riformulerò la domanda: il seguente codice è sufficiente per generare tutti i caratteri validi non controllati in Unicode ?

unicode_glyphs = ''.join(
    unichr(char)
    for char in xrange(1114112) # 0x10ffff + 1
    if unicodedata.category(unichr(char))[0] in ('LMNPSZ')
    )


Dal momento che Unicode è solo un intervallo di - well - codes, per quanto riguarda l'utilizzo di unichr () per ottenere la stringa unicode corrispondente a un numero casuale compreso tra 0 e 0xFFFF?
(Ovviamente questo darebbe solo un punto di codice, quindi iterare come richiesto)


Ecco una funzione di esempio che probabilmente crea una sequenza UTF-8 casuale ben formata, come definito nella Tabella 3-7 di Unicode 5.0.0:

#!/usr/bin/env python3.1

# From Table 3–7 of the Unicode Standard 5.0.0

import random

def byte_range(first, last):
    return list(range(first, last+1))

first_values = byte_range(0x00, 0x7F) + byte_range(0xC2, 0xF4)
trailing_values = byte_range(0x80, 0xBF)

def random_utf8_seq():
    first = random.choice(first_values)
    if first <= 0x7F:
        return bytes([first])
    elif first <= 0xDF:
        return bytes([first, random.choice(trailing_values)])
    elif first == 0xE0:
        return bytes([first, random.choice(byte_range(0xA0, 0xBF)), random.choice(trailing_values)])
    elif first == 0xED:
        return bytes([first, random.choice(byte_range(0x80, 0x9F)), random.choice(trailing_values)])
    elif first <= 0xEF:
        return bytes([first, random.choice(trailing_values), random.choice(trailing_values)])
    elif first == 0xF0:
        return bytes([first, random.choice(byte_range(0x90, 0xBF)), random.choice(trailing_values), random.choice(trailing_values)])
    elif first <= 0xF3:
        return bytes([first, random.choice(trailing_values), random.choice(trailing_values), random.choice(trailing_values)])
    elif first == 0xF4:
        return bytes([first, random.choice(byte_range(0x80, 0x8F)), random.choice(trailing_values), random.choice(trailing_values)])

print("".join(str(random_utf8_seq(), "utf8") for i in range(10)))

A causa della vastità dello standard Unicode, non riesco a verificarlo a fondo. Si noti inoltre che i caratteri non sono equamente distribuiti (ma ogni byte nella sequenza è).


Le persone possono trovare la loro strada qui basandosi principalmente sul titolo della domanda, quindi ecco un modo per generare una stringa casuale contenente una varietà di caratteri Unicode. Per includere più (o meno) caratteri possibili, estendi semplicemente quella parte dell'esempio con gli intervalli di punti di codice che desideri.

import random

def get_random_unicode(length):

    try:
        get_char = unichr
    except NameError:
        get_char = chr

    # Update this to include code point ranges to be sampled
    include_ranges = [
        ( 0x0021, 0x0021 ),
        ( 0x0023, 0x0026 ),
        ( 0x0028, 0x007E ),
        ( 0x00A1, 0x00AC ),
        ( 0x00AE, 0x00FF ),
        ( 0x0100, 0x017F ),
        ( 0x0180, 0x024F ),
        ( 0x2C60, 0x2C7F ),
        ( 0x16A0, 0x16F0 ),
        ( 0x0370, 0x0377 ),
        ( 0x037A, 0x037E ),
        ( 0x0384, 0x038A ),
        ( 0x038C, 0x038C ),
    ]

    alphabet = [
        get_char(code_point) for current_range in include_ranges
            for code_point in range(current_range[0], current_range[1] + 1)
    ]
    return ''.join(random.choice(alphabet) for i in range(length))

if __name__ == '__main__':
    print('A random string: ' + get_random_unicode(10))

Rispondere alla domanda riveduta:

Sì, su una definizione rigorosa di "caratteri di controllo": nota che non includerai CR, LF e TAB; È questo che vuoi?

Per favore, considera la possibilità di rispondere al mio precedente invito a dirci cosa stai realmente cercando di fare.


Segue un codice che stampa qualsiasi carattere stampabile di UTF-8:

print(''.join(tuple(chr(l) for l in range(1, 0x10ffff)
                    if chr(l).isprintable())))

Tutti i personaggi sono presenti, anche quelli che non sono gestiti dal carattere usato. and not chr(l).isspace() può essere aggiunto per filtrare tutti i caratteri dello spazio. (compresa la scheda)







random