2010-02-27 18 views
6

Necesito saber cuántas sustituciones ha realizado Powershell al utilizar el operador -replace o el método Replace(). O, si eso no es posible, si hizo algún reemplazo.Powershell, ¿cuántos reemplazos hizo usted?

Por ejemplo, en Perl, porque la operación de sustitución devuelve el número de sustituciones realizadas, y el cero es falso mientras no nulo es cierto en un contexto booleano, se puede escribir:

$greeting = "Hello, Earthlings"; 
if ($greeting ~= s/Earthlings/Martians/) { print "Mars greeting ready." } 

Sin embargo, con Powershell el operador y el método devuelven la nueva cadena. Parece que el operador proporciona cierta información adicional, si uno sabe cómo solicitarla (por ejemplo, los grupos capturados se almacenan en una nueva variable que crea en el alcance actual), pero no puedo averiguar cómo obtener un conteo o valor de exito

Podría simplemente comparar los valores de antes y después, pero parece totalmente ineficiente.

Respuesta

8

Tienes razón, no creo que puedas exprimir nada extra. Sin embargo, puede encontrar el número de coincidencias usando Regex.Matches(). Por ejemplo

> $greeting = "Hello, Earthlings" 
> $needle = "l" 
> $([regex]::matches($greeting, $needle)).Length # cast explicitly to an array 
3 

Puede utilizar el operador -replace que usa el mismo motor que hace juego.


Después de mirar un poco más profundo, hay una sobrecarga de Reemplazar que tiene un delegado MatchEvaluator que se llama cada vez que se produce una coincidencia. Entonces, si usamos eso como un acumulador, puede contar la cantidad de reemplazos de una vez.

> $count = 0 
> $matchEvaluator = [System.Text.RegularExpressions.MatchEvaluator]{$count ++} 
> [regex]::Replace("Hello, Earthlings","l",$matchEvaluator) 
> $count 
Heo, Earthings 
3 
+0

gran solución! –

+0

Esto no funciona para mí en PS 3/Windows 8. El reemplazo funciona, pero el recuento de $ es 0. Sin embargo, SÍ funciona cuando ejecuto la emulación PS 2 (a través de powershell -versión 2). – bart

+2

Descubrí que esto se debe a un cambio documentado en las notas de la versión de Windows Management Framework 3: "Los bloques de scripts ejecutados como delegados se ejecutan en su propio ámbito". Hacer $ count global resuelve el problema. – bart

0

versión del guión que realmente no reemplazar las cosas y no es nulo ellos:

$greeting = "Hello, earthlings. Mars greeting ready" 
$counter = 0 
$search = '\s' 
$replace = '' 
$evaluator = [System.Text.RegularExpressions.MatchEvaluator] { 
    param($found) 
    $counter++ 
    Write-Output ([regex]::Replace($found, [regex] $search, $replace)) 
} 

[regex]::Replace($greeting, [regex] $search, $evaluator); 
$counter 

->

> Hello,earthlings.Marsgreetingready 
> 4