Domanda

Sto importando alcuni dati da a CSV file e numeri più grandi di 1000 trasformarsi in 1,100 eccetera.

Qual è un buon modo per rimuovere sia le virgolette che la virgola da questo in modo da poterlo inserire in un file int campo?

Modificare:

I dati in realtà sono già in una tabella MySQL, quindi devo essere in grado di farlo utilizzando SQL.Mi spiace per il disguido.

È stato utile?

Soluzione

Ecco un buon caso per le espressioni regolari.È possibile eseguire una ricerca e sostituzione sui dati prima dell'importazione (più semplice) o successivamente se l'importazione SQL ha accettato tali caratteri (non altrettanto semplice).Ma in entrambi i casi, hai un numero qualsiasi di metodi per eseguire una ricerca e sostituzione, che si tratti di editor, linguaggi di scripting, programmi GUI, ecc.Ricorda che vorrai trovare e sostituire Tutto dei personaggi cattivi.

Una tipica espressione regolare per trovare la virgola e le virgolette (assumendo solo virgolette doppie) è: (Lista nera)

/[,"]/

Oppure, se trovi che qualcosa potrebbe cambiare in futuro, questa espressione regolare corrisponde a qualsiasi cosa tranne un numero o un punto decimale. (Lista bianca)

/[^0-9\.]/

Ciò che è stato discusso dalle persone sopra è che non conosciamo tutti i dati nel tuo file CSV.Sembra che tu voglia rimuovere le virgole e le virgolette da tutti i numeri nel file CSV.Ma poiché non sappiamo cos'altro c'è nel file CSV, vogliamo assicurarci di non corrompere altri dati.Il semplice fatto di eseguire una ricerca/sostituzione alla cieca potrebbe influire su altre parti del file.

Altri suggerimenti

La mia ipotesi qui è che, poiché i dati sono stati in grado di importare, il campo è in realtà un varchar o un campo di caratteri, perché l'importazione in un campo numerico potrebbe non essere riuscita.Ecco un caso di test in cui ho eseguito esclusivamente una soluzione MySQL, SQL.

  1. La tabella è solo una singola colonna (alfa) che è un varchar.

    mysql> desc t;
    
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | alpha | varchar(15) | YES  |     | NULL    |       | 
    +-------+-------------+------+-----+---------+-------+
    
  2. Aggiungi un record

    mysql> insert into t values('"1,000,000"');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t;
    
    +-------------+
    | alpha       |
    +-------------+
    | "1,000,000" | 
    +-------------+
    
  3. Dichiarazione di aggiornamento.

    mysql> update t set alpha = replace( replace(alpha, ',', ''), '"', '' );
    Query OK, 1 row affected (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    mysql> select * from t;
    
    +---------+
    | alpha   |
    +---------+
    | 1000000 | 
    +---------+
    

Quindi alla fine l'affermazione che ho usato è stata:

UPDATE table
   SET field_name = replace( replace(field_name, ',', ''), '"', '' );

Ho guardato il Documentazione MySQL e non sembrava che potessi trovare le espressioni regolari e sostituire.Anche se potresti, tipo Eldila, utilizza un'espressione regolare per trovare e quindi una soluzione alternativa per sostituire.


Fai attenzione anche con s/"(\d+),(\d+)"/$1$2/ perché cosa succede se il numero contiene più di una sola virgola, ad esempio "1.000.000" vorrai fare una sostituzione globale (in Perl questo è s///g).Ma anche con una sostituzione globale la sostituzione inizia da dove l'avevi interrotta l'ultima volta (a meno che perl non sia diverso) e mancherebbe ogni altro gruppo separato da virgole.Una possibile soluzione sarebbe rendere il primo (\d+) facoltativo in questo modo s/(\d+)?,(\d+)/$1$2/g e in questo caso avrei bisogno di una seconda ricerca e sostituzione per eliminare le virgolette.

Ecco alcuni esempi di espressioni regolari che agiscono solo sulla stringa "1.000.000", nota che NON ci sono virgolette doppie all'interno della stringa, questa è solo una stringa del numero stesso.

>> "1,000,000".sub( /(\d+),(\d+)/, '\1\2' )
# => "1000,000"  
>> "1,000,000".gsub( /(\d+),(\d+)/, '\1\2' )
# => "1000,000"  
>> "1,000,000".gsub( /(\d+)?,(\d+)/, '\1\2' )
# => "1000000"  
>> "1,000,000".gsub( /[,"]/, '' )
# => "1000000"  
>> "1,000,000".gsub( /[^0-9]/, '' )
# => "1000000"

Potresti usare questo comando perl.

Perl -lne 's/[,|"]//; print' file.txt > newfile.txt

Potrebbe essere necessario giocarci un po', ma dovrebbe funzionare.

Ecco il modo PHP:

$stripped = str_replace(array(',', '"'), '', $value);

Collegamento alla pagina W3Schools

In realtà nlucaroni, il tuo caso non è del tutto corretto.Il tuo esempio non include virgolette doppie, quindi

id,age,name,...
1,23,phil,

non corrisponderà alla mia espressione regolare.Richiede il formato "XXX,XXX".Non riesco a pensare a un esempio di quando corrisponderà in modo errato.

Tutti gli esempi seguenti non includeranno il delimitatore nella regex:

"111,111",234
234,"111,111"
"111,111","111,111"

Per favore fatemi sapere se vi viene in mente un controesempio.

Saluti!

La soluzione alla domanda modificata è sostanzialmente la stessa.

Dovrai eseguire la query di selezione con la clausola regex where.

Qualcosa del genere

Select *
  FROM SOMETABLE
  WHERE SOMEFIELD REGEXP '"(\d+),(\d+)"'

Per ciascuna di queste righe, vuoi eseguire la seguente sostituzione regex s/"(\d+),(\d+)"/$1$2/ e quindi aggiornare il campo con il nuovo valore.

Per favore Joseph Pecoraro seriamente e fai un backup prima di apportare modifiche di massa a qualsiasi file o database.Perché ogni volta che esegui regex, puoi seriamente confondere i dati se ci sono casi che ti sono sfuggiti.

Il mio comando rimuove tutti i ',' e '"'.

Per convertire la puntura "1.000" in modo più rigoroso, avrai bisogno del seguente comando.

Perl -lne 's/"(\d+),(\d+)"/$1$2/; print' file.txt > newfile.txt

La risposta di Daniel ed Eldila presenta un problema:Rimuovono tutte le virgolette e le virgole nell'intero file.

Quello che faccio di solito quando devo fare qualcosa del genere è sostituire prima tutte le virgolette di separazione e (di solito) i punti e virgola con tabulazioni.

  • Ricerca: ";"
  • Sostituire:

Poiché so in quale colonna saranno i miei valori interessati, eseguo un'altra ricerca e sostituisco:

  • Ricerca: ^([ ]+) ([ ]+) ([0-9]+),([0-9]+)
  • Sostituire: \1 \2 \3\4

...dato che il valore con la virgola è nella terza colonna.

Devi iniziare con un "^" per assicurarti che inizi all'inizio di una riga.Quindi ripeti ([0-9]+) tutte le volte che ci sono colonne che vuoi lasciare così come sono.

([0-9]+),([0-9]+) cerca i valori in cui è presente un numero, poi una virgola e poi un altro numero.

Nella stringa di sostituzione utilizziamo \1 e \2 per mantenere solo i valori della riga modificata, separandoli con (tab).Quindi inseriamo \3\4 (senza tabulazione in mezzo) per mettere i due componenti del numero senza la virgola uno dopo l'altro.Tutti i valori successivi verranno lasciati invariati.

Se hai bisogno che il tuo file contenga un punto e virgola per separare gli elementi, puoi andare avanti e sostituire le tabulazioni con il punto e virgola.Tuttavia, se tralasci le virgolette, dovrai assicurarti che i valori del testo non contengano punti e virgola stessi.Ecco perché preferisco utilizzare TAB come separatore di colonna.

Di solito lo faccio in un normale editor di testo (EditPlus) che supporta RegExp, ma le stesse espressioni regolari possono essere utilizzate in qualsiasi linguaggio di programmazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top