LOOT LOOT
Regular Expression - Regex

The purpose of this page is to provide detailed information for using Regex while editing a masterlist, as well as searching specific terms within it. Regular expressions can formally be described as follows:

A regular expression (shortened as regex or regexp) is a sequence of characters that specifies a search pattern in text.

General

Advantages of Regex

Let's take a look at DragonPriest Retexture for a first example:

The DragonPriest Retexture mod includes the two different plugins AcolyteMasks.esl and AcolyteMasks.esp. If we want to add a url for each plugin, we could write the masterlist entry like this:


  - name: 'AcolyteMasks.esl'
    url:
      - link: 'https://www.nexusmods.com/skyrimspecialedition/mods/41713/'
        name: 'DragonPriest Retexture'

  - name: 'AcolyteMasks.esp'
    url:
      - link: 'https://www.nexusmods.com/skyrimspecialedition/mods/41713/'
        name: 'DragonPriest Retexture'

This writing-style is a valid method to add metadata to the masterlists and it also means that searching for the plugin entry (e.g. AcolyteMasks.esl) is fast and easy, as it is exactly the same as the actual plugin name.

The downside to it is however, that these non-regex entries take up more space than their regex counterparts, as we have added the same link twice to the masterlist. In order to keep things maintainable, we often choose to make use of regular expressions such as the following one:

  - name: 'AcolyteMasks\.es(l|p)'
    url:
      - link: 'https://www.nexusmods.com/skyrimspecialedition/mods/41713/'
        name: 'DragonPriest Retexture'

Three different aspects have been changed respectively added in order for this regular expression to work.

Both plugins AcolyteMasks.esl and AcolyteMasks.esp will now have their locations displayed in LOOT.

Regex within LOOT

Now that we taken the first step to understand what regular expressions are, it should be noted that LOOT uses three different regex implementations in different places.

This means, that depending on where you want to use a regular expression within LOOT, unicode characters for character matching might be supported or not.

  - name: 'Example\.es(m|p)'
    msg:
      - <<: *useOnlyOneX
        subs: [ 'Example Plugin' ]
        condition: 'many("Example\.es(m|p)")'

The regex in the name field uses C++'s standard regex, which doesn't support unicode.

The regex in the condition field uses the Rust regex library, which supports unicode by default.

Regex_Search_Cards

The search dialog uses Qt's regex implementation, which doesn't support unicode characters by default (though support may be enabled in a future LOOT release).

Regex_Filter_Contain

The contains filter uses C++'s standard regex, which doesn't support unicode.

The following section will concentrate on the use of regex in the name field of plugin objects in the masterlist, so that we get a better understanding of what is possible while adding and updating plugin entries.

Characters and Rules

The following regular expressions can be used to match characters:

\d \D \w \W \s \S

In order to get a feeling what sorts of characters these expressions are capable of matching, let's take the following set of characters as reference:

Digits:

0 1 2 3 4 5 6 7 8 9

Latin Alphabet:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Additional Latin Characters:

Ä Æ Ö Ü

Special Characters:

! # $ % & ( ) , . ' ` - ; [ ] ^ _ { } ~ € + = Œ ੩

Greek Alphabet:

α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ ς τ υ φ χ ψ ω

Japanese Hiragana:

あ い う え お か き く け こ さ し す せ そ た ち つ て と な に ぬ ね の は ひ ふ へ ほ ま み む め も や ゆ よ ら り る れ ろ わ を ん

Japanese Katakana:

ア イ ウ エ オ カ キ ク ケ コ サ シ ス セ ソ タ チ ツ テ ト ナ ニ ヌ ネ ノ ハ ヒ フ ヘ ホ マ ミ ム メ モ ヤ ユ ヨ ラ リ ル レ ロ ワ ヲ ン

Through testing the following rules could be derived:

Regex while Editing

Quantifiers

Once or none: ?

Exemplary masterlist entry: Map Markers Complete

  - name: 'Map Markers Complete( DLC| nC| OC)?\.esp'
    url:
      - link: 'https://www.nexusmods.com/skyrim/mods/25603/'
        name: 'Map Markers Complete'

Plugins that are identified by the above Regex:

Map Markers Complete.esp
Map Markers Complete DLC.esp
Map Markers Complete nC.esp
Map Markers Complete OC.esp

Summary:

Zero or more times: *

Exemplary masterlist entry:

  - name: 'Bashed Patch.*\.esp'
    group: *dynamicPatchGroup
    after:
      - 'SSEMerged.esp'
      - 'One ImCh Patch.esp'
      - 'One ImCh Patcher.esp'

Plugins that are identified by the above Regex:

Bashed Patch, 0.esp
Bashed Patch, 1.esp
Bashed Patch, 2.esp
...

Summary:

This means, that in addition to it's standard name Bashed Patch, 0.esp (and also Bashed Patch, 1.esp and Bashed Patch, 2.esp) the following variants would be found by the Regex as well:

Bashed Patch.esp
Bashed Patch_.esp
Bashed PatchAAA.esp

This goes to show that the above Regex is designed so that it may find differently named Bashed Patch plugins, even though Bashed Patch, 0.esp is and will always be the standard nomenclature for Bashed Patches.

For Wrye Bash the filename of the plugin doesn't matter to begin with, as it is identifying Bashed Patches through the plugins author field containing BASHED PATCH within it.

Also see: Wrye Bash General Readme

One or more times: +

Exemplary masterlist entry: Rich Skyrim Merchants

  - name: 'RichMerchantsSkyrim_x\d+\.esp'
    url:
      - link: 'https://www.nexusmods.com/skyrimspecialedition/mods/1772/'
        name: 'Rich Skyrim Merchants'
    tag: [ Relev ]

Plugins that are identified by the above Regex:

RichMerchantsSkyrim_x2.esp
RichMerchantsSkyrim_x5.esp
RichMerchantsSkyrim_x10.esp

Summary:

Exactly x times: {x}

Exemplary masterlist entry: Enhanced Vegetation

  - name: 'Enhanced Vegetation \[\d{3}%\]\.esp'
    url: [ 'https://www.nexusmods.com/oblivion/mods/23783/' ]
    msg:
      - <<: *useOnlyOneX
        subs: [ 'Enhanced Vegetation' ]
        condition: 'many("Enhanced Vegetation \[\d{3}%\]\.esp")'

Plugins that are identified by the above Regex:

Enhanced Vegetation [100%].esp
Enhanced Vegetation [110%].esp
Enhanced Vegetation [125%].esp
Enhanced Vegetation [150%].esp

Summary:

x or more times: {x,}

Exemplary masterlist entry:

  - name: 'Example \d{3,}\.esp'
    msg:
      - type: say
        content:
          - lang: en
            text: 'A few lines from Skyrim.ini: {0}'
          # Other languages omitted for brevity
        subs:
          - |

            ```
            [Audio]
            fMusicDuckingSeconds=6.0
            fMusicUnDuckingSeconds=8.0
            fMenuModeFadeOutTime=3.0
            fMenuModeFadeInTime=1.0
            ```

Plugins that are not identified by the above Regex:

Example 1.esp
Example 12.esp

Plugins that are identified by the above Regex:

Example 123.esp
Example 1234.esp

Summary:

x to y times (inclusive): {x,y}

Exemplary masterlist entry: Arrowsmith - Reupload | ArrowsmithES

  - name: 'Arrowsmith\w{0,2}\.esp'
    msg:
      - *alreadyInSkyRe
      - *alreadyInCompleteCraftingOverhaul

Plugins that are identified by the above Regex:

Arrowsmith.esp
ArrowsmithES.esp

Summary:

Character Classes

One of the characters in brackets: [ ... ]

Exemplary masterlist entry: Lanterns Of Skyrim II

  - name: '(Lanterns Of Skyrim II|LoS II - .*)\.es[mp]'
    url:
      - link: 'https://www.nexusmods.com/skyrimspecialedition/mods/30817/'
        name: 'Lanterns Of Skyrim II'

Plugins that are identified by the above Regex:

Lanterns Of Skyrim II.esm
LoS II - 3DNPC addon.esp
LoS II - BlackthornManor patch.esp
LoS II - Book of Skyrim patch.esp
LoS II - Bruma patch.esp
LoS II - Camp Argentum patch.esp
LoS II - Convenient Bridges patch.esp
LoS II - CEO Windhelm patch.esp
LoS II - ClefJ Winterhold patch.esp
LoS II - CRF patch.esp
LoS II - Camp Varglya patch.esp
LoS II - Campfire addon.esp
LoS II - Dragon Bridge patch.esp
LoS II - Darkwater Crossing patch.esp
LoS II - Eli's Breezehome patch.esp
LoS II - ELFX patch.esp
LoS II - Eli's Riverwood Shack patch.esp
LoS II - Enhanced Solitude SSE patch.esp
LoS II - ETaC patch.esp
LoS II - Fortified Whiterun patch.esp
LoS II - Falkreath patch.esp
LoS II - Helarchen Creek patch.esp
LoS II - HelgenReborn patch.esp
LoS II - Ivarstead patch.esp
LoS II - JKs Skyrim patch.esp
LoS II - JKs Riverwood patch.esp
LoS II - Karthwasten patch.esp
LoS II - Kynesgrove patch.esp
LoS II - Lantern Workers.esp
LoS II - LotD patch.esp
LoS II - Midwood Isle patch.esp
LoS II - Northern Marsh Bridges patch.esp
LoS II - Obscure College of Winterhold patch.esp
LoS II - Old Hroldan Ruins patch.esp
LoS II - Oakwood patch.esp
LoS II - Overstead SE patch.esp
LoS II - RiverwoodHuntingCabin patch.esp
LoS II - Run of the Mill Inn patch.esp
LoS II - Skyrim Bridges patch.esp
LoS II - Solitude Docks patch.esp
LoS II - Solitude Expansion patch.esp
LoS II - Settlements Expanded patch.esp
LoS II - SMIM patch.esp
LoS II - Shor's Stone patch.esp
LoS II - Sounds of Skyrim patch.esp
LoS II - Soljund's Sinkhole patch.esp
LoS II - The Fall of Granite Hill patch.esp
LoS II - TGCoR - SLaWF patch.esp
LoS II - Telengard patch.esp
LoS II - USSEP patch.esp
LoS II - Whistling Mine patch.esp
LoS II - Weathered Road Signs patch.esp

Summary:

Exemplary masterlist entry: Coins of Tamriel SSE

  - name: 'Coins of Tamriel( V[234])? SSE( Hardcore)? Edition\.esp'
    url: [ 'https://www.nexusmods.com/skyrimspecialedition/mods/6441/' ]

Plugins that are identified by the above Regex:

Coins of Tamriel SSE Edition.esp
Coins of Tamriel V2 SSE Edition.esp
Coins of Tamriel V3 SSE Edition.esp
Coins of Tamriel V4 SSE Edition.esp

Coins of Tamriel SSE Hardcore Edition.esp
Coins of Tamriel V2 SSE Hardcore Edition.esp
Coins of Tamriel V3 SSE Hardcore Edition.esp
Coins of Tamriel V4 SSE Hardcore Edition.esp

Summary:

Range x to y: [x-y]

Exemplary masterlist entry:

  - name: 'cc[A-Z]{3}SSE[0-9]{3}.*\.es(l|m)'
    group: *ccGroup

A few examples of plugins that are identified by the above Regex:

ccBGSSSE001-Fish.esm
ccBGSSSE025-AdvDSGS.esm
ccBGSSSE037-Curios.esl
ccQDRSSE001-SurvivalMode.esl

For more information on Creation Club plugins, see UESPWiki - Creation Club.

Summary:

One character that is not x: [^x]

Exemplary masterlist entry:

    - &scriptExtenderMissing
      type: error
      content: 'You have installed an {0} plugin but {0} was not found! See {0} download page: {1}.'
      subs:
        - 'SKSE'
        - '[SKSE](https://skse.silverlock.org)'
      condition: 'file("SKSE/Plugins/([^\.]+\.dll)") and not file("../skse_loader.exe")'

Here is a small overview of SKSE Plugins which are identified by the above Regex (this list does not claim to be complete):

SKSE Plugin Mod
AHZmoreHUDPlugin.dll moreHUD
BugFixPlugin.dll Bug fixes
chargen.dll RaceMenu
ConsolePlugin.dll ConsoleUtil
CopyPaste.dll Copy and Paste in Console
CrashFixPlugin.dll Crash fixes
DisplayEnemyLevel.dll Display Enemy Level
DoubleJumpPlugin.dll Better Jumping
DynamicAnimationReplacer.dll Dynamic Animation Replacer
fiss.dll FileAccess Interface for Skyrim Script - FISS
FloatingDamage.dll Floating Damage
havok_fix.dll (SKSE) Havok Fix
LipSyncFix.dll Fix Lip Sync
LocationalDamage.dll Locational Damage
nioverride.dll RaceMenu
PlayerRotation.dll Player Rotation in ShowRaceMenu
po3_namedashpiles.dll Name Those Ash Piles
po3_papyrusextender.dll powerofthree's Papyrus Extender
po3_SpellPerkItemDistributor.dll Spell Perk Item Distributor
po3_WashThatBloodOff.dll Wash That Blood Off
QuickLoot.dll Quick Loot
SkyrimSouls.dll SkyrimSouls - Unpaused Game Menus
StorageUtil.dll Campfire - Complete Camping System

Summary:

Lookarounds

Negative lookahead: (?! ...)

Exemplary masterlist entry: Kalilies NPCs

  - name: '.*(KaliliesNPC|Kalilies NPC)(?! WARP).*\.esp'
    url: [ 'https://www.nexusmods.com/skyrimspecialedition/mods/30247/' ]

Plugins that are identified by the above Regex:

AI Overhaul - KaliliesNPCs Patch.esp
CRF - Kalilies NPC's Patch.esp
KaliliesNPCs.esp
KaliliesNPCs - CRF patch.esp
KaliliesNPCs - USSEP CRF AI Overhaul Patch.esp
Kalilies NPCs + AI Overhaul + Cutting Room Floor Patch.esp

Summary:

More Examples

Requiem

Exemplary masterlist entry: Requiem - The Roleplaying Overhaul

  - name: 'Requiem( - (No (Overencumbered )?Messages|Restored (Rewarding Sounds|Saving Messages)|Vanilla Dragonborn DLC))?\.esp'
    url:
      - link: 'https://www.nexusmods.com/skyrim/mods/19281/'
        name: 'Requiem - The Roleplaying Overhaul'

Plugins that are identified by the above Regex:

Requiem.esp
Requiem - No Messages.esp
Requiem - No Overencumbered Messages.esp
Requiem - Restored Rewarding Sounds.esp
Requiem - Restored Saving Messages.esp
Requiem - Vanilla Dragonborn DLC.esp

Summary:

Skyrim Project Optimization

Exemplary masterlist entry: Skyrim Project Optimization SE

  - name: 'Skyrim Project Optimization - (No Homes - )?Full( ESL)? Version\.esm'
    url:
      - link: 'https://www.nexusmods.com/skyrimspecialedition/mods/14084/'
        name: 'Skyrim Project Optimization SE'

Plugins that are identified by the above Regex:

Skyrim Project Optimization - Full ESL Version.esm
Skyrim Project Optimization - Full Version.esm
Skyrim Project Optimization - No Homes - Full ESL Version.esm
Skyrim Project Optimization - No Homes - Full Version.esm

Summary:

Regex while Searching

General

The LOOT masterlists are .yaml files that include thousands of lines and data for many different plugins. Sometimes and for specific reasons we found it useful to make use of regular expressions while searching different terms within the masterlists.

For example, in Notepad++ you can switch from the Search Mode Normal to Regular expression to use the following examples.

Notepad_Regex_01

Examples

Find - name: '' entries followed by url

Regular Expression:

- name: '\w{1,}\.\w{3}'\r?\n.*url

Exemplary search result:

  - name: 'SimSettlements.esm'
    url: [ 'https://www.nexusmods.com/fallout4/mods/21872' ]
    after:
      - 'HUDFramework.esm'
      - 'WorkshopFramework.esm'

Summary:

Find - name: '' entries not followed by url

Regular Expression:

- name: '\w{1,}\.\w{3}'\r?\n.*(after|clean|dirty|^display|group|inc|msg|req)

Exemplary search result:

  - name: 'PPF.esm'
    clean:
      # English
      - crc: 0x92CA557D
        util: 'FO4Edit v4.0.4b'

Summary:

If the display key would not be excluded, false positive search results such as the following one would be found:

  - name: 'SS2.esm'
    url:
      - link: 'https://www.nexusmods.com/fallout4/mods/47976/'
        name: 'Sim Settlements 2 (Nexus Mods)'
      - link: 'https://bethesda.net/en/mods/fallout4/mod-detail/4183663/'
        name: 'Sim Settlements 2 (Bethesda.net Mods)'
    inc:
      - name: 'Conquest.esp'
        display: 'Conquest - Build New Settlements and Camping'
Find instances of trailing whitespaces after - name: ''

Regular Expression:

- name: '\w{1,}\.\w{3}'\s$

Exemplary search result (notice the whitespace at the end):

  - name: 'Homemaker.esm'
    url: [ 'https://www.nexusmods.com/fallout4/mods/1478/' ]

What is not found:

  - name: 'Homemaker.esm'
    url: [ 'https://www.nexusmods.com/fallout4/mods/1478/' ]

Summary:

Find instances of single line location data

Regular Expression:

url:\s\[

Exemplary search result:

  - name: 'SettlementKeywords.esm'
    url: [ 'https://www.nexusmods.com/fallout4/mods/12226/' ]

What is not found:

  - name: 'ColterFix.esp'
    url:
      - link: 'https://www.nexusmods.com/fallout4/mods/59323/'
        name: 'Overboss Colter Fix'

Summary:

Find plugins with x dirty edits

Regular Expression:

\w{3}: \d{x}

Exemplary search result for x = 4:

  - name: 'Little Cottage on a Hill.esp'
    url:
      - link: 'https://www.nexusmods.com/skyrim/mods/22773/'
        name: 'Little Cottage on a Hill'
    dirty:
      # v1.0
      - <<: *reqManualFix
        crc: 0xAB8573E8
        util: '[TES5Edit v4.0.4b](https://www.nexusmods.com/skyrim/mods/25859)'
        itm: 2733
        udr: 44
        nav: 1

Summary:

Find Creation Club plugins

Regular Expressions:

cc\w{3}sse\d{3}

cc\w{3}fo4\d{3}

Exemplary search results:

  - name: 'ccfsvsse001-backpacks.esl'
    clean:
      - crc: 0x3F8D2754
        util: 'SSEEdit v4.0.4'

  - name: 'ccbgsfo4076-pipmystery.esl'
    clean:
      - crc: 0x3FAFF472
        util: 'FO4Edit v4.0.2j'

Summary:

Find block style single-element lists

Lists that have only one element that aren't written in flow style can look like the after tag in the following example:

  - name: 'InnoLostAlt.esp'
    url: [ 'https://www.nexusmods.com/skyrimspecialedition/mods/24236' ]
    after:
      - 'TheChoiceIsYours.esp'
    clean:
      - crc: 0x7D8AB5D7
        util: 'SSEEdit v4.0.3'

For consistency reasons we instead write these list like this:

    after: [ 'TheChoiceIsYours.esp' ]

The following regular expression can be used to find such instances:

: *\r?\n {3,}-.*\r?\n {2,4}(?! )

Additional exemplary search results:

  - name: 'after_clean.esp'
    after:
      - 'TheChoiceIsYours.esp'
    clean:

  - name: 'msg_clean_1.esp'
    msg:
      - *includesMBBF
    clean:

  - name: 'msg_clean_2.esp'
    msg:
      - <<: *patchRequiem3rdParty
        condition: 'not checksum("Rebirth Monster.esp", 3F7371A1)'
        subs:
          - '[Revenge of the Enemies Patches](https://www.nexusmods.com/skyrim/mods/73369)'
    clean:

  - name: 'tag_clean.esp'
    tag:
      - Stats
    clean:

Summary:

While this regex is already great in finding single-element lists, it wouldn't find these instances:

  - name: 'after_without_clean.esp'
    after:
      - 'TheChoiceIsYours.esp'

  - name: 'msg_without_clean.esp'
    msg:
      - *includesMBBF

  - name: 'tag_without_clean.esp'
    tag:
      - Stats

The expression can be improved to find these instances as well:

: *\r?\n {3,}-.*\r?\n( {2,4}(?! )|\r?\n+)

While the improved regex already finds all of the above examples, it also finds the following case, which is a false positive search result:

  - name: 'Example \d{3,}\.esp'
    msg:
      - type: say
        content:
          - lang: en
            text: 'A few lines from Skyrim.ini: {0}'
          # Other languages omitted for brevity
        subs:
          - |

            ```
            [Audio]
            fMusicDuckingSeconds=6.0
            fMusicUnDuckingSeconds=8.0
            fMenuModeFadeOutTime=3.0
            fMenuModeFadeInTime=1.0
            ```

The regex can once again be improved to exclude the above false positive:

: *\r?\n {3,}-[^\r?\n|]*\r?\n( {2,4}(?! )|\r?\n+)
Revisit merger bash tags

Regular Expressions:

(\[|-|:) *(Actors\.Perks|Invent|Outfits|(R\.)?Relations|Derel)

Exemplary search results:

  - name: 'DeadMoney.esm'
    tag:
      - Deflst
      - Invent.Add
      - Invent.Remove

  - name: 'KDS Wearable Backpacks.esp'
    tag: [ Invent ]

  - name: 'NewVegasBountiesII.esp'
    tag: [ Relations ]

Summary:

Find NoMerge bash tags

Regular Expressions:

(\[|-|:) *NoMerge

Exemplary search results:

  - name: 'FNVMerged.esp'
    tag: [ NoMerge ]

  - name: 'Realistic Weight.esp'
    tag:
      - NoMerge
      - Stats

What is not found:

bash_tags:
  - 'NoMerge'

# NoMerge

Summary:

Find & Replace

General

Find & Replace is a feature of e.g. Notepad++ as well as VSCode, to easily find a specific term and replace it with another, with a single button press.

This presents a great possibility to go through larger tasks that otherwise would need a lot of manual work, however masterlist maintainers should refrain from using automated Replace All functions.

This would certainly decrease the time needed to work on the task at hand, however it would also come with an elevated risk to miss something or replace some parts that weren't intended to be replaced.

Examples

Replace file extension
Find:
.esp

Replace:
.esl

Summary:

Replace Invent Bash Tag
Find:
\s{6}-\sInvent$

Replace:
      - Test

Summary:

Add missing trailing slashes to Nexus Mods url
Find:
/mods/(\d{1,})'

Replace:
/mods/\1/'

Exemplary search result:

  - name: 'Altitude.esp'
    url: [ 'https://www.nexusmods.com/newvegas/mods/71404' ]

Replacement:

  - name: 'Altitude.esp'
    url: [ 'https://www.nexusmods.com/newvegas/mods/71404/' ]

Summary:

Update location data to include a name
Find:
\s{4}url: \[\s(.*)\s\]

Replace:
    url:\r\n      - link: \1\r\n        name: ''
Notepad_Regex_02

Exemplary search result:

  - name: 'Altitude.esp'
    url: [ 'https://www.nexusmods.com/newvegas/mods/71404/' ]

Replacement:

  - name: 'Altitude.esp'
    url:
      - link: 'https://www.nexusmods.com/newvegas/mods/71404/'
        name: ''

Summary: