Utiliser Powershell pour remplacer le paragraphe de regex résultat
À l'aide de Powershell, je sais comment rechercher un fichier pour les complexes de la chaîne à l'aide d'une regex, et de la remplacer avec une partie fixe de la valeur, comme dans l'extrait suivant:
Get-ChildItem "*.txt" |
Foreach-Object {
$c = ($_ | Get-Content)
$c = $c -replace $regexA,'NewText'
[IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
}
Maintenant, je suis à essayer de comprendre comment remplacer un paragraphe de chaque match d'une regex. Cela peut être fait en une seule étape, comme ci-dessus? Ou avez-vous de l'extrait de chaque match de la plus grande regex, de recherche et de remplacement à l'intérieur, puis en quelque sorte bâton que le résultat dans le texte original?
À clarifier avec un exemple, supposons que dans le test suivant le texte, je veux trouver les 14xx-numéroté instances comme "TEST=*1404" dans le texte suivant, et de remplacer le 14xx avec 16xx?
A 2180 1830 12 0 3 3 TEST=C1404
A 900 1830 12 0 3 3 TEST=R1413
A 400 1830 12 0 3 3 TEST=R1411
A 1090 1970 12 0 3 3 TEST=U1400
A 1090 1970 12 0 3 3 TEST=CSA1400
A 1090 1970 12 0 3 3 TEST=CSA1414
A 1090 1970 12 0 3 3 TEST=CSA140
A 1090 1970 12 0 3 3 TEST=CSA14001
A 1090 1970 12 0 3 3 TEST=CSA17001
I. e. J'aimerais que le texte comme suit, où vous pourrez noter que seules les 6 premières lignes doivent changer:
A 2180 1830 12 0 3 3 TEST=C1604
A 900 1830 12 0 3 3 TEST=R1613
A 400 1830 12 0 3 3 TEST=R1611
A 1090 1970 12 0 3 3 TEST=U1600
A 1090 1970 12 0 3 3 TEST=CSA1600
A 1090 1970 12 0 3 3 TEST=CSA1614 <- Second instance of '14' shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA140 <- Shorter numbers shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA14001 <- Longer numbers shouldn't change
A 1090 1970 12 0 3 3 TEST=CSA17001
Suivantes regex semble faire le travail de trouver les plus grandes chaînes où j'ai besoin de faire des remplacements, mais je ne sais pas ce que la fonctionnalité en Powershell (replace
?) à utiliser pour remplacer la chaîne de résultats. Aussi, n'hésitez pas à suggérer une meilleure regex.
$regexA = "\bTEST=\b[A-Za-z]+14\d\d\r"
Je préfère ne pas avoir à coder en dur une liste exhaustive de ce qui peut venir entre le " = "et le nombre, comme "R", "C", "CSA", etc.
J'ai été travailler sur quelque chose pour une heure ou deux où je reçois tous les matches pour les regex, de la recherche à l'intérieur d'eux pour remplacer 14 à 16, puis exécutez le remplacer sur le texte original, avec les valeurs anciennes et nouvelles, par exemple replace($myText,"TEST=CSA1400","TEST=CSA1600")
, mais ce n'est pas couvrant hors les cas spéciaux très bien, et il se sent comme je suis tête en bas le lapin-trou.
OriginalL'auteur SSilk | 2013-11-11
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin de regrouper les sous-expressions vous souhaitez conserver (c'est à dire de les mettre entre parenthèses) et puis de référence les groupes à l'aide des variables
$1
et$2
dans la chaîne de remplacement. Essayez quelque chose comme ceci:Dans votre méthode, est-il un danger pour l'ajout d'un
-raw
à laGet-Content
et la suppression de lajoin
de la pièce de rechange?Cela devrait fonctionner aussi, mais vous avez besoin de remplacer le
$
dans l'expression régulière avec quelque chose comme(\r|$)
.Une autre question: que faire si la valeur que je suis coller dans le milieu est lui-même une autre variable, externe à l'expression régulière, plutôt que d'une valeur fixe. E. g. si le
16
dans votre exemple de code ont été certaines variables$number
, que dois-je faire pour l'avoir reconnu en tant que tel? Quand j'ai essayer avec votre code, littéralement imprime le nom de la variable avec$
. Merci.Si vous souhaitez utiliser des variables dans la chaîne de remplacement, vous devez utiliser des guillemets au lieu de guillemets simples, et d'échapper à l'variables de référencement sur les groupes à partir de l'expression régulière:
"`$1$number`$2"
.OriginalL'auteur Ansgar Wiechers
Voici un exemple d'utilisation d'un scriptblock délégué (parfois appelé un évaluateur):
C'est sans doute plus complexe que l'-remplacer l'opérateur, mais vous permet d'utiliser powershell opérateurs pour construire le texte de remplacement, de sorte que vous pouvez faire ce que vous pouvez mettre dans un bloc de script.
OriginalL'auteur mjolinor
Essayez ceci:
$f = $_.FullName; (Get-Content $f) -replace ... | Out-File $f ...
est probablement un plus élégant approche.OriginalL'auteur Keith Hill