Search code examples
cssregexpowershell

Edit a css file using a regular expression in Powershell


Excerpt of my current theme.css file:

.actionBlock[selected] {
        color: var(--gray11);
        background-color: var(--gray11);
    }

I want change color: var(--gray11); into color: #FFF; /* EDITED : var(--gray11) */

In PowerShell, I tried:

$file = "theme.css"
$content = Get-Content $file -Raw
$content = $content -replace '(\.actionBlock\[selected\]\s*{[^{}]+color:\s*)([^;]+)(;)', ('$1#FFF; /* EDITED : $2 */')
Set-Content -Path $file -Value $content

This resulted in changing my CSS like this:

.actionBlock[selected] {
        color: var(--gray11);
        background-color: #FFF; /* EDITED : var(--gray11) */
    }

Which is not the result that I expected: I want to change only the color value, not the background-color value.


Solution

  • Your regex is actually almost fine, you just need to make [^{}]+ match lazily by adding ?. See https://regex101.com/r/K6HTYG/1.

    $css = @'
    .actionBlock[selected] {
      color: var(--gray11);
      background-color: var(--gray11);
    }
    '@
    
    $css -replace '(\.actionBlock\[selected\]\s*{[^{}]+?color:\s*)([^;]+)(;)', '$1#FFF; /* EDITED : $2 */'
    

    However this would fail fairly easily as soon as color were after background-color, so perhaps a better approach is to look for the line where color is preceded only by white space. See https://regex101.com/r/99QdN3/1.

    $css = @'
    .actionBlock[selected] {
      background-color: var(--gray11);
      color: var(--gray11);
    }
    '@
    
    $css -replace '(?m)(?<=\.actionBlock\[selected\]\s*{[^{}]+?^\s*color:\s*)([^;]+);', ' #FFF; /* EDITED :$1 */'