Diciamo che ho una stringa "La volpe marrone veloce salta sul cane pigro" posso cambiare questo a "La volpe marrone lenta salta sul cane energico" con una sola espressione regolare? Attualmente, io uso due serie di espressioni regolari per questa situazione. (In questo caso, utilizzo s/quick/slow/
seguito da s/lazy/energetic/
.)Posso sostituire più elementi in una singola espressione regolare in VIM o Perl?
risposta
La seconda parte di una sostituzione è una stringa doppia citata, pertanto è possibile che si verifichi un'interpolazione normale. Ciò significa che è possibile utilizzare il valore della cattura di indicizzare in un hash:
#!/usr/bin/perl
use strict;
use warnings;
my %replace = (
quick => "slow",
lazy => "energetic",
);
my $regex = join "|", keys %replace;
$regex = qr/$regex/;
my $s = "The quick brown fox jumps over the lazy dog";
$s =~ s/($regex)/$replace{$1}/g;
print "$s\n";
È possibile effettuare quanto segue.
:%s/quick\(.*\)lazy/slow\1energetic
Il trucco è quello di utilizzare le parentesi per abbinare il testo tra le due parole. È quindi possibile fare riferimento a questo testo nella stringa di sostituzione utilizzando \1
. È inoltre possibile utilizzare \2
per la seconda espressione di paren corrispondente e così via. Ciò consente di sostituire più parole senza disturbare il testo tra di esse.
E se ci sono molte occorrenze di rapida e pigro che sono intercalati? – allyourcode
@allyourcode, quindi sostituirà la coppia più esterna. Questo è solo leggermente differente dall'esempio di Tg che sostituirà il primo occurance. – JaredPar
in Perl:
s/quick(.*)lazy/slow${1}energetic/;
In vim:
s/quick\(.*\)lazy/slow\1energetic/;
C'è un modo pulito per farlo in Ruby utilizzando gsub con un blocco:
s = "The quick brown fox jumps over the lazy dog"
subs = {'quick' => 'slow', 'lazy' => 'industrious'}
s.gsub(/quick|lazy/) { |match| subs[match] }
# => "The slow brown fox jumps over the industrious dog"
È possibile farlo in vim utilizzando un dizionario:
:%s/quick\|lazy/\={'quick':'slow','lazy':'energetic'}[submatch(0)]/g
Questo cambierà il seguente testo:
Il rapido marrone volpe correva rapido mente accanto alla pigro ruscello.
in:
Il lento marrone volpe correva lento mente accanto alla energico ruscello.
Per vedere come funziona, vedere :help sub-replace-expression
e :help Dictionary
. In breve,
\=
consente di sostituire il risultato di un'espressione vim.{'quick':'slow', 'lazy':'energetic'}
è un dizionario Vim (come un hash in perl o rubino o un oggetto in javascript) che utilizza[]
per le ricerche.submatch(0)
è la stringa corrispondente
Questo può tornare utile durante il refactoring del codice - dicono di voler modificare i nomi delle variabili per foo
, bar
, e baz
cambiando
foo
→bar
bar
→baz
baz
→foo
Utilizzando una sequenza di comandi %s///
sarebbe difficile, a meno che non utilizzato nomi di variabili temporanee - ma che avrebbe dovuto assicurarsi che coloro che non stavano colpendo qualsiasi altra cosa. Invece, è possibile utilizzare un dizionario per farlo in un solo passaggio:
:%s/\<\%(foo\|bar\|baz\)\>/\={'foo':'bar','bar':'baz','baz':'foo'}[submatch(0)]/g
che cambia questo codice
int foo = 0;
float bar = pow(2.0, (float) foo);
char baz[256] = {};
sprintf(baz,"2^%d = %f\n", foo, bar);
in:
int bar = 0;
float baz = pow(2.0, (float) bar);
char foo[256] = {};
sprintf(foo,"2^%d = %f\n", bar, baz);
Se vi trovate a fare questo molto, potresti aggiungere quanto segue al tuo ~/.vimrc
:
" Refactor the given lines using a dictionary
" replacing all occurences of each key in the dictionary with its value
function! Refactor(dict) range
execute a:firstline . ',' . a:lastline . 's/\C\<\%(' . join(keys(a:dict),'\|'). '\)\>/\='.string(a:dict).'[submatch(0)]/ge'
endfunction
command! -range=% -nargs=1 Refactor :<line1>,<line2>call Refactor(<args>)
Questa opzione consente di utilizzare il comando :Refactor {'frog':'duck', 'duck':'frog'}
ed è leggermente meno ripetitivo di rispetto alla creazione manuale di regex per il dict. risposta
Chas è buona, l'unica altra cosa che vorrei menzionare è che se si sta facendo di parola swap probabilmente si desidera essere corrispondenti a
\ b (foo | bar | baz | qux) \ b
per evitare sottostringhe corrispondenti. Se si fa un sacco di parola scambio, si potrebbe iniziare a trovare espressioni regolari un po 'limitanti e voglia di fare qualcosa di simile:
join '', map { exists $subst{$_} ? $subst{$_} : $_ } split /\b/, $string
È possibile concatenare sostituzioni Vim:
Il quick brown fox corse velocemente vicino al ruscello pigro.
:s/quick/slow/|s/lazy/energetic/
La lenta volpe marrone correva rapidamente accanto al ruscello energico.
Il vantaggio è che si deve digitare le vostre sostituzioni solo una volta
Rgds
Non una singola espressione regolare come richiesto dalla domanda, ma +1 per la migliore soluzione alla parte vim del problema, IMHO. Grazie! –
- 1. Espressione regolare sostituire
- 2. Sostituire un'occorrenza con espressione regolare
- 3. Sostituire una stringa corrispondente certa espressione regolare con la sua lunghezza in Vim
- 4. Espressione regolare - Ruby vs Perl
- 5. Espressione regolare, sostituire più barre con un solo
- 6. espressione regolare java trovare e sostituire
- 7. Espressione regolare multilinea in C#
- 8. Espressione regolare in sed per più sostituzioni in un'unica istruzione
- 9. Espressione regolare per sostituire spazi con trattini
- 10. Sostituire il gruppo di cattura specifico anziché l'intera espressione regolare in Perl
- 11. Sostituire un regolare submatch espressione utilizzando una funzione
- 12. Confrontare più variabili con un valore in una singola espressione
- 13. Sostituire tutte le corrispondenze con valori in regolare espressione Ruby
- 14. Come posso espandere un'impostazione o una variabile in un'espressione regolare Vim?
- 15. Perl6: Cattura di una nuova riga di Windows in una stringa con espressione regolare
- 16. Perl scissione e di espressione regolare
- 17. Utilizzo di un'espressione regolare per sostituire lettere maiuscole ripetute in python con una singola lettera minuscola
- 18. Espressione regolare sostituisci in C#
- 19. Espressione regolare per sostituire i numeri in un file
- 20. Python String.Replace espressione regolare
- 21. Espressione regolare: inizio partita o spazio vuoto
- 22. Converti una stringa in espressione regolare rubino
- 23. ripetendo più personaggi espressione regolare
- 24. Cosa significa `?` In questa espressione regolare di Perl?
- 25. espressione regolare in iOS
- 26. espressione Scala per sostituire un'estensione di file in una stringa
- 27. Come posso sostituire i caratteri Unicode con ASCII in Perl?
- 28. Espressione regolare in Bash Script
- 29. Perl sostituire più stringhe contemporaneamente
- 30. Espressione regolare sostituita in Visual Studio
Hai dimenticato il modificatore 'e'. –
Cosa fa? valutare la sostituzione? C'è qualcosa di simile in altri linguaggi di programmazione? – allyourcode
Non ha bisogno/e perché è una semplice interpolazione, prova il codice prima di fare affermazioni. –