Skip to main content

Command Palette

Search for a command to run...

Regex to the Rescue

Updated
3 min read

Everyone knows that Regular Expressions can do some pretty extreme searching, but occasionally they can also be used to help you write your code.

Anyone that knows me knows that I love what I call "code that writes code". T4, Velocity, even CodeDom - these are all things I just get giddy to use.

Occasionally, you can use RegEx to the same effect. Take, for instance, a recent feature request I was implementing to allow users to select margins in pixels or percents. Going to the browser and editing the HTML directly therein, I was able to make the changes necessary in a way that would look good to the user.

The above image shows both the original (Margin Right) and the changes I wished to make (Margin Left).

If that was all I needed to do - change those two inputs to each have an additional dropdown, I'd have been done quickly. But it wasn't. The page has default values and then values for 10 more rules. So 22 controls in total.

I could have gone in and changed each of the 22 manually, but that would have been tedious, mind-numbing work, so .....

RegEx to the rescue...

The original code is PHP Volt, and one control looks like this:


<input type="hidden" name="ecm[floatDefaultMarginLeft][configurationID]"
       value="{{ configurations['floatDefaultMarginLeft']['configurationID'] }}"/>
<input type="number" id="floatDefaultMarginLeft" class="form-control"
       name="ecm[floatDefaultMarginLeft][ciValue]"
       value="{{ configurations['floatDefaultMarginLeft']['ciValue'] }}"/>

I needed to change it to look like this:

<input type="hidden" name="ecm[floatDefaultMarginLeft][configurationID]"
       value="{{ configurations['floatDefaultMarginLeft']['configurationID'] }}"/>
<input type="hidden" name="ecm[floatDefaultMarginLeftType][configurationID]"
       value="{{ configurations['floatDefaultMarginLeftType']['configurationID'] }}"/>
<div class="row">
    <div class="col-xs-10 col-md-8 col-lg-9" style="padding-right:0">
        <input type="number" id="floatDefaultMarginLeft" class="form-control"
               name="ecm[floatDefaultMarginLeft][ciValue]"
               value="{{ configurations['floatDefaultMarginLeft']['ciValue'] }}"/>
    </div>
    <div class="col-xs-2 col-md-4 col-lg-3" style="padding-left: 0">
        <select class="form-control" name="ecm[floatDefaultMarginLeftType][ciValue]">
            <option value="%" {% if configurations['floatDefaultMarginLeftType']['ciValue'] == '%' or configurations['floatDefaultMarginLeftType']['ciValue'] is empty %} selected {% endif %}>%</option>
            <option value="px" {% if configurations['floatDefaultMarginLeftType']['ciValue'] == 'px' %} selected {% endif %}>px</option>
        </select>
    </div>
</div>

Of course, all those "MarginLeft"s are "MarginRight" for the right side. And the rules based settings are all "float1MarginLeft" or "float2MarginLeft", etc.

But RegEx has capturing groups, and even named capturing groups. So I ended up with this multiline RegEx:

(?<linespace>\s*)<input type="number" id="float(?<num>\w+)Margin(?<direction>\w+)" class="form-control"
(?<linespace2>\s*)name="ecm\[float(\w+)Margin(\w+)\]\[ciValue\]"
(?<linespace3>\s*)value="{{ configurations\['float(\w+)Margin(\w+)'\]\['ciValue\'\] }}"\/>

And this replacement 'text':


${linespace}<input type="hidden" name="ecm[float${num}Margin${direction}Type][configurationID]"
${linespace2}value="{{ configurations['float${num}Margin${direction}Type']['configurationID'] }}"/>
${linespace}<div class="row">
${linespace}    <div class="col-xs-10 col-md-8 col-lg-9" style="padding-right:0">
${linespace}        <input type="number" id="float${num}Margin${direction}" class="form-control"
${linespace2}        name="ecm[float${num}Margin${direction}][ciValue]"
${linespace3}        value="{{ configurations['float${num}Margin${direction}']['ciValue'] }}"/>
${linespace}    </div>
${linespace}    <div class="col-xs-2 col-md-4 col-lg-3" style="padding-left: 0">
${linespace}        <select class="form-control" name="ecm[float${num}Margin${direction}Type][ciValue]">
${linespace}            <option value="%" {% if configurations['float${num}Margin${direction}Type']['ciValue'] == '%' or configurations['float${num}Margin${direction}Type']['ciValue'] is empty %} selected {% endif %}>%</option>
${linespace}            <option value="px" {% if configurations['float${num}Margin${direction}Type']['ciValue'] == 'px' %} selected {% endif %}>px</option>
${linespace}        </select>
${linespace}    </div>
${linespace}</div>

And voila, 22 changes complete!

So ... use the tools you have at your disposal. Work smart, not hard. And get a good RegEx tool. On Windows 10/11, I recommend Regex Hero, with SkyD Regex a close second.