2011-12-30 6 views
10

Diciamo che ho questo file di testo tabulato:come comprimere gli spazi bianchi in una regione?

field1  variable_length_field variable_length_field 
aaaaaa  aaaa      aaaaaaaaa 
bbbbbb  bbbbbbbbbbbbbbbbbbbb  bbbb 

Come posso trasformarlo a:

field1 variable_length_field variable_length_field 
aaaaaa aaaa aaaaaaaaa 
bbbbbb bbbbbbbbbbbbbbbbbbbb bbbb 

So che potrei usare replace-regexp sulla regione, ma espressioni regolari emacs non sono naturalmente . Stavo cercando qualcosa come delete-whitespace-rectangle, ma questo non fa quello che mi aspetto, o lo sto abusando. Avere la capacità di fare questo per-colonna sarebbe troppo desiderabile, vale a dire:

field1  variable_length_field variable_length_field 
aaaaaa  aaaa aaaaaaaaa 
bbbbbb  bbbbbbbbbbbbbbbbbbbb bbbb 
+0

Da dove viene il _rectangle_ in questo? – sarnold

+0

Ci sono due rettangoli che possono essere compressi in una colonna ciascuno, ma per trovarli è necessario eseguire la scansione, presupponendo che i campi dati non abbiano una larghezza fissa. – seh

+0

Si dice che il file è "tabulato", che prendo per non dire che lo spazio di separazione è tab caratteri, ma piuttosto che i campi sono allineati a sinistra. È il caso che nessuno dei campi possa contenere spazi bianchi? – seh

risposta

13

Questa funzione dovrebbe fare il trucco:

(defun just-one-space-in-region (beg end) 
    "replace all whitespace in the region with single spaces" 
    (interactive "r") 
    (save-excursion 
    (save-restriction 
     (narrow-to-region beg end) 
     (goto-char (point-min)) 
     (while (re-search-forward "\\s-+" nil t) 
     (replace-match " "))))) 

E, dal momento che la domanda è stata aggiornata da applicare a spazi in un rettangolo, provate questo:

(require 'rect) 
(defun just-one-space-in-rect-line (start end) 
    (save-restriction 
    (save-match-data 
     (narrow-to-region (+ (point) start) 
         (+ (point) end)) 
     (while (re-search-forward "\\s-+" nil t) 
     (replace-match " "))))) 
(defun just-one-space-in-rect (start end) 
    "replace all whitespace in the rectangle with single spaces" 
    (interactive "r") 
    (apply-on-rectangle 'just-one-space-in-rect-line start end)) 
+0

Questo è quasi perfetto. Questo funziona per un'intera regione ma non per i rettangoli, domanda chiarita. – user525602

+1

seconda versione è perfetta! Stavo cercando di imparare come usare i rettangoli in elisp ieri per risolvere questo problema, ma non sono riuscito a farlo bene. Questo è un ottimo esempio da cui imparare. Grazie! – user525602

0

si sta utilizzando un IDE? Se stai usando qualcosa come Eclipse, allora puoi formattare le opzioni di spazi bianchi al suo interno. (In Eclipse, premi CTRL + 3 e cerca 'formattatore'. Mi scuso per non aver ricordato il percorso esatto!) Quindi, dovresti essere in grado di evidenziare tutto e premere ctrl + mai + G per auto = formattare tutto.

Facci sapere se è utile! (Oppure, se vuoi codice di rotazione che farà questo, facci sapere la lingua.)

+1

"Emacs" è elencato in entrambi i tag _and_ body della domanda. :) – sarnold

+0

Scusaci, ancora nuovo! In bocca al lupo. – Salmontres

3

Puoi gestire i tuoi requisiti di rettangolo usando le funzioni di modifica del rettangolo in modalità cua *.

  1. M-xcua-selection-modeRET o (cua-selection-mode 1)
    (io, io ho questo abilitata in modo permanente).

  2. Contrassegnare il rettangolo all'interno del quale si desidera comprimere lo spazio, utilizzando C-RET e i normali tasti di spostamento.

  3. chiamata cua-replace-in-rectangle:
    M-r\s-+RETSPCRET

  4. C-RET di nuovo per terminare la modifica rettangolo.

(*) Questo non funziona se avete bisogno di campi a destra del rettangolo di rimanere allineati, come in questo caso si avrebbe bisogno di inserire nuovi spazi per compensare quelli che sono stati rimossi. Potresti usare 2C-split e 2C-merge o semplicemente uccidere/tirare il rettangolo più a destra per ovviare a questo.

+0

Sono appena arrivato a questa risposta. Ti dispiacerebbe spiegare perché '\ s- +' corrisponde a un numero qualsiasi di spazi? Capisco che '\ s' è uno spazio, e che' + 'significa uno o più, ma perché il segno' -'? –

+2

No, '\ s' non significa uno spazio (n.b. non tutte le lingue regex sono uguali!). In Emacs, '\ s' indica un carattere della * sintassi * indicato dal carattere successivo. Il codice '-' è per la classe di sintassi degli spazi bianchi. Puoi anche usare uno spazio invece di un trattino, ma il trattino è più leggibile. Vedi 'C-h i g (elisp) Regexp Backslash RET' e poi cerca nella pagina '\ sCODE' – phils

9

Non proprio rispondere alla tua domanda, ma c'è

M-SPC runs the command just-one-space, which is an interactive 
compiled Lisp function in `simple.el'. 

It is bound to M-SPC. 

(just-one-space &optional N) 

Delete all spaces and tabs around point, leaving one space (or N spaces). 

[back] 

che è utile quando si desidera eliminare gli spazi bianchi in una tantum casi. Potrebbe essere adatto per un caso macro in cui le delezioni sono a righe casuali senza schema fisso.