Dovrei usare \ d o per abbinare le cifre in un’espressione regolare Perl?

Avendo letto una serie di domande / risposte nelle ultime settimane, ho visto l’uso di \d in perl espressioni regolari commentate come errate. Come nelle versioni successive di perl \d non è uguale a [0-9] , poiché \d rappresenterà qualsiasi carattere Unicode che ha l’attributo digit, e che [0-9] rappresenta i caratteri ‘0’, ‘1 ‘,’ 2 ‘, …,’ 9 ‘.

Apprezzo che in alcuni contesti [0-9] sia la cosa giusta da usare, e in altri \d lo sarà. Mi stavo chiedendo quali persone ritengono sia l’impostazione predefinita corretta da utilizzare?

Personalmente trovo la notazione \d molto succinta ed espressiva, mentre in confronto [0-9] è alquanto macchinosa. Ma ho poca esperienza di fare codice multi-lingua, o piuttosto codice per linguaggi che non rientrano nell’intervallo di caratteri ASCII, e quindi può essere ingenuo.

noto

 $find /System/Library/Perl/5.8.8/ -name \*pm | xargs grep '\\d' | wc -l 298 $find /System/Library/Perl/5.8.8/ -name \*pm | xargs grep '\[0-9\]' | wc -l 26 

Per la massima sicurezza, ti suggerisco di utilizzare [0-9] ogni volta che non intendi specificamente abbinare tutte le cifre definite in Unicode.

Per perldoc perluniintro , Perl non supporta l’uso di cifre diverse da [0-9] come numeri, quindi userò sicuramente [0-9] se le seguenti sono entrambe vere:

  1. Si desidera utilizzare il risultato come numero (ad esempio eseguendo operazioni matematiche su di esso o memorizzandolo da qualche parte che accetta solo numeri corretti (ad es. Una colonna INT in un database)).

  2. È ansible che non siano presenti cifre [^0-9] nei dati in modo che l’espressione regolare possa corrisponderli. (Si noti che questo dovrebbe sempre essere considerato vero per input non fidati / ostili.)

Se uno di questi è falso, ci sarà solo raramente motivo per non usare specificatamente \d (e probabilmente sarai in grado di dire quando è il caso), e se stai cercando di abbinare tutte le cifre definite in modo unicode, sicuramente vuoi usare \d .

Mi sembra molto pericoloso da usare \d , È una decisione di progettazione scarsa nella lingua, come nella maggior parte dei casi si desidera [0-9] . La codifica di Huffman determinerebbe l’uso di \d per i numeri ASCII.

La maggior parte dei poster precedenti ha già evidenziato perché dovresti usare [0-9] , quindi lascia che ti dia un po ‘più di dati:

  • Se leggo correttamente i grafici Unicode, ” ۷۰ ” è un numero (70 in indica, non fidarti della mia parola).

  • Prova questo:

     $ perl -le '$one = chr 0xFF11; print "$one + 1 = ", $one+1;' 1 + 1 = 1 
  • Ecco una lista parziale di numeri validi (che possono o non possono apparire correttamente nel tuo browser, a seconda dei font che usi), per ogni numero, solo il primo di quelli che viene interpretato come un numero quando si eseguono aritmetici con Perl, come mostrato sopra:

      ZERO: 0٠۰߀०০੦૦୦௦౦೦൦๐໐0 ONE: 1١۱߁१১੧૧୧௧౧೧൧๑໑1 TWO: 2٢۲߂२২੨૨୨௨౨೨൨๒໒2 THREE: 3٣۳߃३৩੩૩୩௩౩೩൩๓໓3 FOUR: 4٤۴߄४৪੪૪୪௪౪೪൪๔໔4 FIVE: 5٥۵߅५৫੫૫୫௫౫೫൫๕໕5 SIX: 6٦۶߆६৬੬૬୬௬౬೬൬๖໖6 SEVEN: 7٧۷߇७৭੭૭୭௭౭೭൭๗໗7 EIGHT: 8٨۸߈८৮੮૮୮௮౮೮൮๘໘8 NINE: 9٩۹߉९৯੯૯୯௯౯೯൯๙໙9   

Non sei ancora convinto?

Secondo perlreref , ‘ \d ‘ è consapevole delle impostazioni internazionali e Unicode.

Tuttavia, se il set di codici che stai utilizzando non è Unicode, non devi preoccuparti delle cifre Unicode e se il set di codici che stai utilizzando è qualcosa come Latin-1 (ISO 8859-1 o 8859-15), quindi la consapevolezza della localizzazione non ti farà male perché il codeset non include nessun altro carattere numerico.

Quindi, per molte persone, il più delle volte, puoi usare ” \d ” senza problemi. Tuttavia, se i dati Unicode fanno parte del tuo lavoro, devi considerare attentamente ciò che stai cercando.

Proprio come nuotare il sito dall’orbita, [0-9] è l’unico modo per esserne sicuri. Sì, è brutto. Sì, la scelta di rendere UNICODE e le impostazioni locali erano stupide. Ma questo è il nostro letto e dobbiamo mentirci.

Per quanto riguarda le persone che abbassano la testa nella sabbia dicendo che non influenza il set di caratteri che stanno usando oggi, beh, potresti usare quel set di caratteri oggi, ma il resto del mondo sta usando UTF-8 ora e tu sarai usarlo presto pure. Ricordati di scrivere come il tipo che mantiene il tuo codice è un maniaco omicida che sa dove vivi.

Oh, e come per i moduli Perl che usano \d vs [0-9] , anche il core ha ancora problemi UNICODE .

Se in realtà si intende qualsiasi cifra, ma si desidera essere in grado di fare matematica con i risultati, è ansible utilizzare Text::Unidecode :

 #!/usr/bin/perl use strict; use warnings; use Text::Unidecode; my $number = "\x{1811}\x{1812}\x{1813}\x{1814}\x{1815}"; print "$number is ", unidecode($number), "\n"; 

Dopo altri test, sembra che Text :: Unidecode non gestisca correttamente tutti i caratteri numerici. Sto scrivendo un modulo che funzionerà.

Sento che entrambi devono avere il loro posto. Tuttavia, il 99,999% delle volte (specialmente nel mio grande mondo di cooperazione americano chiuso) sono intercambiabili. Uso perl per manipolare i dati ogni giorno e in nessuno dei set di dati con cui ho a che fare ci sono numeri che non rientrano in [0-9] . Tuttavia, apprezzo che ci sia un’importante distinzione tra \d e [0-9] ed è bene essere consapevoli di questa differenza. Io uso \d perché sembra più succinto (come hai detto tu) e non sarebbe mai “sbagliato” nel mio piccolo mondo di manipolazione dei dati.

Se si applica \d a una stringa Unicode (ad esempio in "\X{660}" =~ /\d/ ), corrisponderà a una cifra Unicode. Se si applica \d a una stringa binaria (come l’equivalente UTF-8 di quanto sopra: "\xd9\xa0" =~ /\d/ ), corrisponderà solo alle 10 cifre ASCII. Perl 5.8 non crea stringhe Unicode per impostazione predefinita (a meno che non lo chiedi espressamente, come in "\X{...}" o use utf8; ecc.).

Quindi il mio consiglio è: prestare attenzione alla differenza tra \d e [0-9] se l’applicazione utilizza stringhe Unicode.

Se [0-9] sembra goffo forse potresti definire: $d=qr/[0-9]/; e usa quello invece di \d .

Quando i controlli sul formato dei dati aumentano, la necessità della specificità del modello diminuisce …

Ad esempio, se si sta abbinando un dato che è stato generato dalla macchina e segue sempre le stesse regole di formattazione dell’output, non è necessario essere così precisi. Prendi gli indirizzi IPv4. se stai cercando di estrarre l’indirizzo IP da una linea di configurazione dell’interfaccia del router, tutto ciò di cui hai veramente bisogno è qualcosa del tipo:

  'ip\haddress\h(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\D' 

Se, d’altra parte, stai cercando di trovare un indirizzo IP inserito in profondità da qualche parte dentro, per esempio, un X-Header di e-mail, o se stai provando a VALIDARE un indirizzo IP, beh … questa è tutta una storia!