2016-07-10 18 views
1

Ich habe eine Eingabedatei, die einige Startdaten enthält und wenn diese Daten vor einem bestimmten Datum sind 1995-01-01 (YYYY-MM-DD-Format), dann das Datum mit dem Minimalwert ersetzen z.B.Powershell - Regex Datumsbereich ersetzen

<StartDate>1970-12-23</StartDate> 

würde

<StartDate>1995-01-01</StartDate> 

<StartDate>1996-05-12</StartDate> geändert werden ist in Ordnung und würde unverändert bleiben.

Ich hatte gehofft, Regex ersetzen zu verwenden, aber die Überprüfung des Datumsbereichs funktioniert nicht wie erwartet. Ich hatte gehofft, so etwas wie dies für den Bereich verwenden

\b(?:1900-01-(?:3[01]|2[1-31])|1995/01/01)\b 

Antwort

2

Sie eine einfache regex wie '<StartDate>(\d{4}-\d{2}-\d{2})</StartDate>' können <StartDate>, 4 Ziffern entsprechen, -, 2-stellig, -, 2-stellig und </StartDate>, und dann einen Rückruf verwenden Methode, das in Gruppe 1 aufgezeichnete Datum zu analysieren und Martins Code dort zu verwenden, um Daten zu vergleichen. Wenn das Datum vor dem festgelegten Datum liegt, verwenden Sie das Mindestdatum, andernfalls das verwendete Datum.

$callback = { 
    param($match) 
    $current = [DateTime]$match.Groups[1].Value 
    $minimum = [DateTime]'1995-01-01' 

    if ($minimum -gt $current) 
    { 
    '<StartDate>1995-01-01</StartDate>' 
    } 
    else { 
    '<StartDate>' + $match.Groups[1].Value + '</StartDate>' 
    } 
} 

$text = '<StartDate>1970-12-23</StartDate>' 
$rex = [regex]'<StartDate>(\d{4}-\d{2}-\d{2})</StartDate>' 
$rex.Replace($text, $callback) 

enter image description here

es nutzen zu können, mit Get-Content und Foreach-Object, können Sie die $callback wie oben definiert und

$rex = [regex]'<StartDate>(\d{4}-\d{2}-\d{2})</StartDate>' 
(Get-Content $path\$xml_in) | ForEach-Object {$rex.Replace($_, $callback)} | Set-Content $path\$outfile 
+0

Sie müssen weiterhin das 'Regex'-Objekt verwenden, da '-replace' keinen Rückruf als Ersatz unterstützt. Probieren Sie '(Get-Content $ infile) | ForEach-Objekt {$ rex.Replace ($ _, $ Rückruf)} | Set-Content $ outfile' –

+0

Ich ziehe dies aus einer Datei mit mehreren Zeilen, also kann ich es mit einem Get-Content und Foreach-Objekt (vorausgesetzt, $ _ ist die Variable für die aktuelle Zeile) (Get-Content $ Pfad \ $ xml_out) | Foreach-Objekt {$ rex = [Regex] ' (\ d {4} - \ d {2} - \ d {\} <\StartDate>', $ rex.Replace ($ _, $ Rückruf)} | set-content $ path \ $ xml_out – zoomzoomvince

+0

Sie sollten keine '$ rex' innerhalb von' Foreach-Object' zuweisen. Weisen Sie '$ rex' davor und nur einmal zu, und verwenden Sie es wie oben gezeigt (Ich habe es in meiner PowerShell in Win7 getestet, und es funktioniert). –

1

Sie überprüfen müssen nicht regex hier verwenden. werfen Sie einfach die Daten zu DateTime und vergleichen sie:

$currentDate = [DateTime]'1970-12-23' 
$minDate = [DateTime]'1995-01-01' 

if ($minDate -gt $currentDate) 
{ 
    $currentDate = $minDate 
} 
+1

Es ist nicht nur über das Datum verwenden. Das OP sollte auch keine Regex für das XML-Parsing verwenden. Powershell hat eingebaute XML-Fähigkeiten, es ist nicht besonders schwierig, dies richtig zu machen. – Tomalak