Notepad++ Copy and Replace

I needed to copy part of a string in the middle of a string and past it in another part of the same string using Notepad++.

In this particular case I was trying to generate color palettes the lazy way; using Notepad++s' find and replace function as it supports regular expressions.

I started with a color hex code (#3f51b5) and went to http://mcg.mbitson.com/ to generate a full palette for it. Now I'm working in XAML right now so I needed to results to be in a different format than any of the options on the site. I chose the closest option on there, ANDROID XML resulting in something similar to what's below.

<resources>
     <color name="blue_50">#e8eaf6</color>
     <color name="blue_100">#c5cbe9</color>
     <color name="blue_200">#9fa8da</color>
     <color name="blue_300">#7985cb</color>
     <color name="blue_400">#5c6bc0</color>
     <color name="blue_500">#3f51b5</color>
     <color name="blue_600">#394aae</color>
     <color name="blue_700">#3140a5</color>
     <color name="blue_800">#29379d</color>
     <color name="blue_900">#1b278d</color>
     <color name="blue_A100">#c6cbff</color>
     <color name="blue_A200">#939dff</color>
     <color name="blue_A400">#606eff</color>
     <color name="blue_A700">#4757ff</color>
<resources>

This is very different from how XAML wants the colors defined. So, I did a few simple find and replaces to get this:

<!-- ... other colors -->
<Color x:Key="Blue400">#5c6bc0</Color>
<Color x:Key="Blue500">#3f51b5</Color>
<Color x:Key="Blue600">#394aae</Color>
<!-- yet more colors... -->

Now the colors have been defined but next you should define the brushes so that you can use the colors in the application. This is where I needed to do the more complicated regex stuff, I'm gonna walk through it in steps.

  1. Used more simple finds and replaces to get down to this:

    <!-- ... other colors -->
    <SolidColorBrush x:Key="Blue400Brush" Color="{StaticResource #5c6bc0}"/>
    <SolidColorBrush x:Key="Blue500Brush" Color="{StaticResource #3f51b5}"/>
    <SolidColorBrush x:Key="Blue600Brush" Color="{StaticResource #394aae}"/>
    <!-- yet more colors... -->
  2. Now I needed to get rid of the hex codes! Enter a little bit of regex magic: #(?<=#)([a-zA-Z0-9]{6}). That will select the # character and the 6 letters and numbers that follow. Just replace with a blank string and bam! No more of those silly hex colors. Resulting in:

    <!-- ... other colors -->
    <SolidColorBrush x:Key="Blue400Brush" Color="{StaticResource }"/>
    <SolidColorBrush x:Key="Blue500Brush" Color="{StaticResource }"/>
    <SolidColorBrush x:Key="Blue600Brush" Color="{StaticResource }"/>
    <!-- yet more colors... -->
  3. Here's the part that took entirely too long. I need to link the Color elements and the SolidColorBrush for every color so that I can just use the color brush in the XAML later down the line. That means to link the color "Blue500" with its brush "Blue500Brush" I need to add the color key to the brush element after the word "StaticResource". I had the name of the color right there in the line so I wanted to see if Notepad++s' find and replace feature would let me just select the Blue500 part of the SolidColorBrush element and copy-paste it after after StaticResource in the same line. Turns out you can!

Make sure the . matches newline box is unchecked and enter (?<=x:Key=")(.*?)(?=Brush)(.*?)(?=}) in the find field. Then put $0$2 in the replace field.

First, know that the parentheses define groups which you can select parts of in the replace field. Group $0 is always match the entire thing then every set of parentheses inside of 0 you can refer to as $1, $2, and so on. When you have (? ... starting the group, you are telling it to match a part of the string but don't include it in the result. Let me break down the expression. Note that ... ?) makes the previous lookup lazy and doesn't stop it from being included as a group. Lets say <SolidColorBrush x:Key="Blue500Brush" Color="{StaticResource }"/> is the current line we are looking at.

  • $0 will match the entire expression. Will be everything between x:Key=" and }, resulting in Blue500Brush" Color="{StaticResource
  • $1 is the first group in the expression (?<=x:Key=")(.*?)(?=Brush) as it's what's in the first set of parentheses that's included as a result. It will match x:Key="Blue500Brush however there are a couple of groups that aren't included in the results! So the real result is whatever is between x:Key=" and Brush resulting finally in Blue500.
  • $2 is everything between the result from $1 to the } character as the final group say to not include the }. The string ends after } so nothing else is caught.

So when you say to replace with $0$1 you are going to replace all of $0 with the $0 and $1 results appended together. Therefor you are finding Blue500Brush" Color="{StaticResource and replacing it with Blue500Brush" Color="{StaticResource ``Blue500. Therefore resulting in <SolidColorBrush x:Key="Blue500Brush" Color="{StaticResource }"/> turning into <SolidColorBrush x:Key="Blue500Brush" Color="{StaticResource Blue500}"/>. Giving me the final result of:

<!-- ... other colors -->
<Color x:Key="Blue400">#5c6bc0</Color>
<Color x:Key="Blue500">#3f51b5</Color>
<Color x:Key="Blue600">#394aae</Color>
<!-- yet more colors... -->

<!-- ... other brushes -->
<SolidColorBrush x:Key="Blue400Brush" Color="{StaticResource Blue400}"/>
<SolidColorBrush x:Key="Blue500Brush" Color="{StaticResource Blue500}"/>
<SolidColorBrush x:Key="Blue600Brush" Color="{StaticResource Blue600}"/>
<!-- yet more brushes... -->

This is so poorly written that it will probably only ever make sense to me. Whatever, good luck out there.