PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mit regulären Ausdrücken in Powershell eine Gruppe formatieren


Morgenlicht
2025-01-22, 16:35:10
Ich schreibe mir gerne mit dem einfachen Notepad-Editor MarkDown-files. Betrachtet werden diese mittels F3 im AltapSalamander. Voraussetzung dabei ist, daß die Pfade der internen Verlinkungen keine Leerzeichen enthalten.

Wenn es denn mal passiert, dass die Markdown-files wo anders liegen, da hab ich mir einen Batch-Datei gebastelt, wobei per DragDrop das ImageVerzeichnis draufgezogen wird und dann reparierte neue MD-Files ausgeschrieben werden. Das funktioniert wunderbar.


$temp = '
sample-1: ![grasspng](C:\Helfer-Powershell\Hilfe\images\getFreeDriveLetter.png) ... sample-2: ![lol](C:/Helfer-Powershell/Hilfe/images/grrr.png)
sample-3: [nochwas](C:\\Helfer-Powershell\\Hilfe\\images\\reicht.png)
'

$imagePath = (Join-Path -Path "Y:\images" -ChildPath "") -replace '\\','//'

$pattern = '(?<=!?\[.*?\]\()(?<Path>[a-z]:.*?)(?=[^\/\\]*?\))'

$temp -replace $pattern , $imagePath
<#

sample-1: ![grasspng](Y://images//getFreeDriveLetter.png) ... sample-2: ![lol](Y://images//grrr.png)
sample-3: [nochwas](Y://images//reicht.png)

#>




Nun aber hab ich lokal einen extrem schlanken Webserver gestartet (www.mengelke.de/Projekte/PHPBatch (https://www.mengelke.de/Projekte/PHPBatch))

Jetzt stehe ich vor der Hürde die internen Verlinkungen der MarkDown-Files so anzupassen, daß diese im Browser korrekt navigiert werden können.

$temp = '
sample-1: ![grasspng](C:\Helfer-Powershell\Hilfe\images\getFreeDriveLetter.png) ... sample-2: ![lol](C:/Helfer-Powershell/Hilfe/images/grrr.png)
sample-3: [nochwas](C:\\Helfer-Powershell\\Hilfe\\images\\reicht.png)
'

$pattern = '(?<=!?\[.*?\]\()(?<Path>.*?\..*?)(?=\))' ;

[regex]::Matches($temp, $pattern) | % {$_.groups} | ft
<#
Groups Success Name Captures Index Length Value
------ ------- ---- -------- ----- ------ -----
{0, Path} True 0 {0} 25 56 C:\Helfer-Powershell\Hilfe\images\getFreeDriveLetter.png
True Path {Path} 25 56 C:\Helfer-Powershell\Hilfe\images\getFreeDriveLetter.png
{0, Path} True 0 {0} 105 42 C:/Helfer-Powershell/Hilfe/images/grrr.png
True Path {Path} 105 42 C:/Helfer-Powershell/Hilfe/images/grrr.png
{0, Path} True 0 {0} 171 50 C:\\Helfer-Powershell\\Hilfe\\images\\re(i)cht.png
True Path {Path} 171 50 C:\\Helfer-Powershell\\Hilfe\\images\\re(i)cht.png
#>

<# Zeile-40 #> [regex]::Matches($temp, $pattern).value | % { "./image-Pfad-Webserver/{0}" -f [system.uri]::EscapeDataString(( Split-Path -Path $_ -Leaf ))}
<#
./image-Pfad-Webserver/getFreeDriveLetter.png
./image-Pfad-Webserver/grrr.png
./image-Pfad-Webserver/re%28i%29cht.png
#>




Man kann zwar mit '$1' oder '${path}' die Gruppe zwar holen, aber nicht irgendwie direkt beim replace umformatieren. Weil im Prinzip würde ich die Gruppe einfach nur damit zurückschreiben wollen;
[system.uri]::EscapeDataString('${Path}')irgendwie stehe ich echt grad auf'n Schlauch wie das umgesetzt wird. Also das die umformatierte "Zeile-40" als Replace genommen wird

konkretor
2025-01-22, 19:41:18
Ich hab mal deine Frage durch Deepseek R1 laufen lassen.
Wäre das für dich ein Ansatz?




Um die Pfade in den Markdown-Links durch Web-URLs mit escapeten Dateinamen zu ersetzen, kannst du einen **Regex-MatchEvaluator** in PowerShell verwenden. Hier ist die Lösung:

```powershell
$temp = @'
sample-1: ![grasspng](C:\Helfer-Powershell\Hilfe\images\getFreeDriveLetter.png) ... sample-2: ![lol](C:/Helfer-Powershell/Hilfe/images/grrr.png)
sample-3: [nochwas](C:\\Helfer-Powershell\\Hilfe\\images\\reicht.png)
'@

$pattern = '(?<=!?\[.*?\]\()(?<Path>.*?\..*?)(?=\))'

$newContent = [regex]::Replace($temp, $pattern, {
param($match)
$oldPath = $match.Groups['Path'].Value
$fileName = $oldPath -split '[\\/]' | Select-Object -Last 1
$escapedName = [System.Uri]::EscapeDataString($fileName)
"./image-Pfad-Webserver/$escapedName"
})

$newContent
```

**Erklärung:**
1. Die Regex `(?<=!?\[.*?\]\()(?<Path>.*?\..*?)(?=\))` findet alle Pfade innerhalb von Markdown-Links
2. Für jeden Match wird der Dateiname aus dem Pfad extrahiert
3. Der Dateiname wird mit `EscapeDataString` URL-kodiert
4. Der neue Pfad wird im Format `./image-Pfad-Webserver/...` generiert

**Ausgabe:**
```
sample-1: ![grasspng](./image-Pfad-Webserver/getFreeDriveLetter.png) ... sample-2: ![lol](./image-Pfad-Webserver/grrr.png)
sample-3: [nochwas](./image-Pfad-Webserver/reicht.png)
```

Dieser Code:
- Behandelt alle Pfadformate (mit / oder \)
- Escapet Sonderzeichen in Dateinamen (z.B. Leerzeichen, Klammern)
- Behält die originale Markdown-Syntax bei
- Funktioniert sowohl für Bilder (`![]()`) als auch normale Links (`[]()`)

Morgenlicht
2025-01-22, 23:39:05
ui :) .. sogar als MarkDown formatiert.

Tatsache, es geht damit :cool: :up:

Da hab ich schon soviel mit regex gemacht und Kilometer darüber gelesen, aber ein Regex-MatchEvaluator kam noch nie vor :eek:

thx, nun hab ich soagr 'nen funktionierendes MatchEvaluator-Beispiel :)

konkretor
2025-01-23, 08:33:29
Regex-MatchEvaluator bist nicht allein mußte erst mal lesen was das macht, regex bleibt voodoo...

Morgenlicht
2025-01-23, 10:14:22
ich liebe mittlerweile regex. Bevor ich damit begann es zu lieben hatte ich alles mit IndexOf()+SubString() und dem hin- und hergerechne gearbeitet. Ok, das mit IndexOf() die Scripte mußte ich tatsächlich seltener, wegen neuer Quellinformation, anpassen.


Nachdem nun das ursprüngliche Problem einen Namen bekommen hat, damit gibt es auf einmal in der googl-suche reichlich Lesestoff. Zuvor bei der Suche wußte ich gar nicht mehr wie ich mein Problem beschreiben sollte :lol: