Powershell -sostituisce il comportamento strano
Questo mi sta facendo impazzire! Apprezzerei qualsiasi suggerimento su cosa sta succedendo, per favore!
$alpha = 'aaa.bbb.$connection.ccc.ddd'
$s = [regex]::match($alpha,"\$.+?(?=\.)").Value "Alpha is: $alpha"
"Matched chunk is: $s" $newChunk = "'" + $s + "'" "New chunk is: $newChunk"
$beta = $alpha -replace $s,$newChunk
"Beta is: $beta"
Questo produce il seguente output:
Alpha is: aaa.bbb.$connection.ccc.ddd
Matched chunk is: $connection New chunk is: '$connection'
Beta is: aaa.bbb.$connection.ccc.ddd
Sto cercando di identificare / far corrispondere sequenze di caratteri in un percorso che inizia con il letterale "$" e continua fino a, ma non include un punto letterale "." char. Nel codice di esempio sopra la stringa sarebbe "$ connection".
Quindi ho bisogno di racchiudere quella stringa tra virgolette singole, quindi nell'esempio sopra il valore $ newChunk diventerebbe '$ connection' comprese le virgolette singole.
Successivamente, è necessario sostituire il valore corrispondente con il nuovo valore tra virgolette singole nella stringa originale. Non importa cosa provo (lo stesso con il metodo [regex] :: match), le virgolette singole vengono rimosse. Quindi, effettivamente, sto cercando di trasformare:
aaa.bbb.$connection.ccc.ddd
in
aaa.bbb.'$connection'.ccc.ddd
Usando Powershell 7.1 e apprezzerei davvero che qualcuno mi dicesse perché questo non funziona. Grazie!
Risposte
Uso
$beta = $alpha -replace '\$[^.]+', "'$&'"
Vedi la prova .
Spiegazione
--------------------------------------------------------------------------------
\$ '$'
--------------------------------------------------------------------------------
[^.]+ any character except: '.' (1 or more times
(matching the most amount possible))
Il $&è il segnaposto per l'intera partita.
L'utile risposta di Ryszard Czech è sicuramente la soluzione migliore : riferirsi genericamente a ciò che l' operatore basato su espressioni regolari ha -replace abbinato, nel suo operando sostitutivo, con segnaposto$& è la soluzione più semplice e robusta.
Vedi questa risposta per altri segnaposto che puoi usare, come ciò che ha preceduto ( $`) o riuscito ( $') la corrispondenza, o ciò che un gruppo di acquisizione corrisponde (ad esempio $1).
Per quanto riguarda quello che hai provato :
Invece di usare la tua regex
\$.+?(?=\.)direttamente con l' operatore basato su regex , hai usato il risultato letterale di una chiamata esplicita come operando di ricerca (primo operando RHS) per , che viene poi nuovamente interpretato come regex.-replace[regex].Match()-replace- Tuttavia, per poter utilizzare una stringa alla lettera come operando di
-replacericerca , qualsiasi metacarattere regex , ovvero caratteri con un significato sintattico speciale, deve essere\preceduto da caratteri di escape , come il verbatim$nella stringa, cosa che puoi fare con[regex]::Escape($s)
- Tuttavia, per poter utilizzare una stringa alla lettera come operando di
Inoltre, hai utilizzato un operando sostitutivo che aveva un carattere incorporato
$. che volevi interpretare alla lettera , ma$nell'operando sostitutivo c'è un metacarattere , che si riferisce a segnaposto come$&.Per utilizzare una stringa verbatim come operando
-replacesostitutivo , è necessario eseguire l' escape dei$caratteri incorporati a livello di codice. come$$[1] :
L'approccio più semplice è quello di utilizzare il[string]metodo di sostituzione letterale-sottostringa del tipo.Replace():$replacementOperand = '$foo' 'value is: (value)' -replace '\(value\)', $replacementOperand.Replace('$', '$$')
Pertanto, il tuo approccio originale avrebbe dovuto utilizzare il seguente comando, ma tieni presente che la soluzione di Ryszard è molto più semplice nel complesso:
$beta = $alpha -replace [regex]::replace($s), $newChunk.Replace('$', '$$')
[1] Situazionalmente potresti $cavartela senza scappare, perché un token -prefixed che non è riconosciuto come segnaposto viene lasciato intatto (ad esempio, 'bar' -replace 'r', '$x'si comporta allo stesso modo di 'bar' -replace 'r', '$$x'), ma l'unica soluzione valida è sfuggire ai $caratteri letterali . raddoppiandoli.