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
- Overview of Regular Expressions: Quick-Start: Regex Cheat Sheet
- Quickly test your Regex: Regular Expressions 101
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.
- The period
.
has been escaped through writing a backslash\
in front of it. This is necessary so that the period is actually recognized as such. Escaping means reducing ambiguity in a more general sense. - After the string
es
follows a capturing group( )
. The content of this capturing group needs to follow what is infront of it. - Inside the capturing group are the letters l and p, seperated by the OR operand
|
. Both letters are valid alternatives for our regex.
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.
- Masterlist entry matching and the contains filter uses
C++
's standard regex. - Condition evaluation uses the Rust
regex
library. - The search dialog uses
Qt
's regex implementation.
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.
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).
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:
\d
can be used exclusively for digits 0 to 9\D
can be used to identify (non-digit) characters from the Latin Alphabet (exceptÄ Æ Ö Ü
) and all the Special Characters\w
can be used for the digits 0 to 9, for any of the normal letters from the Latin Alphabet and for the underscore _\W
can detect exclusively all the special characters except the underscore _ (and no digits or Latin characters)\s
detects whitespace\S
can detect non-whitespace characters: digits, Latin characters (except additional ones) and the special characters- None of the expressions
\d \D \w \W \S
apply for the Greek and Japanese characters
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - After the string
Map Markers Complete
follows a capturing group( )
. - The content of the capturing group has been made optional by adding a question mark
?
directly after it, so both cases of the capturing groups content being present as well as being absent are valid possible matches. - Inside the capturing group are the alternatives
DLC
,nC
andOC
(each string has a leading whitespace), seperated by the OR operand|
.
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - After the string
Bashed Patch
and before the escaping of the period\.
has the term.*
been introduced. - The non-escaped period from
.*
is a regular expression that matches any character except the line break. - The asterisk
*
after the non-escaped period means zero or more times. - Therefore the above Regex matches any plugin name that begins with
Bashed Patch
, after which any sort and number of characters may follow, until.esp
is found.
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - The character
\d
is used to match the digits 0 to 9. - The
+
means one or more times. - The Regex therefore finds
RichMerchantsSkyrim_x
followed by one or more digits.
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - The square brackets
[
and]
have been escaped as well, since otherwise they would be interpreted as a regular expression. - Within the square brackets is the expression
\d{3}
which meaning becomes exactly three digits. - After this expression then comes a
%
, which is a normal character and which is needed because the plugin names include it. - Notice that besides for
name
the regex can also be used forcondition
.
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - The expression
\d{3,}
finds plugins that contain three or more digits. - In addition to the regex this example also showcases a method to display blocks of code within a message for plugins.
- This is achieved through using the Literal Style, which is denoted by the
|
indicator. See yaml.org for more information. - The mentioned
Skyrim.ini
can be found inC:\Users\USER\Documents\My Games\Skyrim
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - As described in the Rules section is the character
\w
used to detect the letters from the Latin alphabet, the underscore_
as well as digits 0 to 9. - The inclusive expression
\w{0,2}
therefore finds strings of length zero to two characters. - The plugin name from the orignal upload is
Arrowsmith.esp
, and the name from from the Spanish translation isArrowsmithES.esp
. The regex\w{0,2}
can now detect whether or notES
is absent or present.
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - The file extension is written as
es[mp]
. Each character in the square brackets is a valid match for the regex, so bothesm
andesp
will be identified by it. - A capturing group
( )
encloses the rest of the plugin name, with the OR operand|
seperating the two alternativesLanterns Of Skyrim II
andLoS II - .*
within it. - The term
.*
within the second alternative consists out of the non-escaped period.
(a regular expression that matches any character except the line break) and the asterisk*
(which means zero or more times). - Therefore the term
LoS II - .*
matches any plugin name that begins withLoS II -
after which any sort and number of characters may follow, until.es[mp]
is found.
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - Six of the eight plugins include either the term
V2
,V3
orV4
. - The expression
V[234]
will find a leading whitespace, followed by the letter V, followed by either 2,3 or 4. - A capturing group encloses
( V[234])?
as the next step. The content of the capturing group has been made optional by adding a question mark?
directly after it, since two of the eight plugins do not include a version number in their name. - The expression
( Hardcore)?
also has been made optional (and includes a leading whitespace), since four of the eight plugins include the word Hardcore, and the other four do not.
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - The file extension is written as
es(l|m)
, so through the use of a capturing group( )
and the OR operand|
bothesl
andesm
are valid matches for the regex. - All Creation Club plugin filenames start with
cc
followed by a set of three varying characters from the Latin alphabet. The regular expression for that is[A-Z]{3}
, so exactly three characters from the range A to Z. - After that all Creation Club plugins for Skyrim Special Edition include
SSE
in their filenames, followed by exactly three digits from the range 0 to 9. The regular expression for that isSSE[0-9]{3}
. - After the three digits follows a hyphen
-
(or in a minority of cases, an underscore_
) followed by a descriptive string such asFish
orSurvivalMode
. - The regular expression
.*
matches these strings, so the non-escaped period.
which finds all characters except the line break, and the asterisk*
that means zero or more.
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:
- The
condition
in this example includes the regular expression:file("SKSE/Plugins/([^\.]+\.dll)")
- The objective is to find
.dll
files within the folder structureSKSE/Plugins/
. - As a first step the period
.
in front ofdll
has been escaped through writing a backslash\
in front of it. - The remaining part of the regex
[^\.]+
consists out of three parts. [^x]
will find a character that is not x, which is achieved by placing the circumflex^
within square brackets[ ]
. In this casex
is an escaped period\.
so not a period is what we want. After the square brackets comes the quantifier plus+
which means one or more times.- Therefore the regular expression
[^\.]+\.dll
finds all SKSE plugins, which filesnames include one or more characters that are not a period, and end with.dll
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - Two capturing groups
( )( )
enclose different parts of the target filenames. - Before and after the two capturing groups is the regular expression
.*
(the non-escaped period.
matches all characters except the line break, and the asterisk*
means zero or more). Placing these before and after the two capturing groups ensures, that around the central stringsKaliliesNPC
andKalilies NPC
any sort and number of characters is matched and found. - Inside the first capturing group is the OR operand
|
so that bothKaliliesNPC
andKalilies NPC
and valid matches. - Inside the second capturing group is the negative lookahead
?! WARP
to exclude any search results that containWARP
in the filename. This is necessary, since otherwise there is a false positive search result in the form ofKaliliesNPCs WARP PATCH.esp
from Kalilies NPCs WARP patch. Since it is the purpose of this regex to provide aurl
for the plugins from the original mod page, and not for the plugin(s) from other mod pages, this is an important and efficient method to achieve the outlined purpose. - It should be noted, that support for lookaround varies by implementation and in LOOT negative lookahead is supported everywhere apart from inside conditions.
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - This regular expression is characterized by the fact that it uses multiple capturing groups that are nested into one another.
- The outer capturing group
( )
comes directly afterRequiem
and it's content it made optional through adding the question mark?
directly after it. - Within this outer capturing group we have the following situation:
- (a|b|c)
with a, b and c being three alternatives seperated by|
- the OR operand. a
isNo (Overencumbered )?Messages
and it has it's own capturing group with the optional contentOverencumbered
.b
isRestored (Rewarding Sounds|Saving Messages)
and it too has it's own capturing group with the non-optional contentRewarding Sounds|Saving Messages
.c
isVanilla Dragonborn DLC
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:
- The period
.
has been escaped through writing a backslash\
in front of it. - All four plugins start with
Skyrim Project Optimization -
and as such, so does the regex. - Two of the four plugins continue on with
No Homes -
and the regex accounts for that with the optional capturing group:(No Homes - )?
- Then all four plugins continue with
Full
and so does the regex. - Two of the four plugins continue on with
ESL
and the regex accounts for that with the optional capturing group:( ESL)?
- All four plugin names and as such the regex end with
Version
and the file extension.
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.
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:
- name: '\w{1,}\.\w{3}'
is the first part of the regex.- Within the two apostrophes
''
the expression\w{1,}
searches for one or more characters of any sort (latin alphabet, digits 0 to 9 and the underscore_
), the escaped period\.
marks the point the file extension begins and\w{3}
is used to find exactly three characters for the file extension (which can either beesm
,esp
oresl
). - The next part of the regex is
\r?\n
. - The combination
\r\n
of the carriage return (CR) character\r
and the line feed (LF) character\n
act together as mechanism to detect a new line of text. It is important to know that while the Windows-style new line consists out of CR LF, files in Git are usually saved with just LF. To ensure that the above regex works in both invironments the question mark?
has been added directly after\r
to make it optional. - The last part of the regex is
.*url
. - It consists out of the non-escaped period
.
which matches all characters except the line break, the asterisk*
which means zero or more and the stringurl
. - The full regex is therefore able to find plugin entries, where directly after the
- name: ''
line the location data with aurl
follows.
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:
- name: '\w{1,}\.\w{3}'\r?\n.*
is exactly the same as in the above regex. The only difference is that instead ofurl
now the capturing group(after|clean|dirty|^display|group|inc|msg|req)
is used.- Inside the capturing group
( )
are the different & alternative keys from the masterlists seperated by the OR operand|
, so that every other one except theurl
is found. - The circumflex
^
is in front ofdisplay
, becausedetail
is never found directly under the mainname
key of a plugin entry.
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:
- name: '\w{1,}\.\w{3}'
is exactly the same as in the above regex.- The potential whitespace is found by
\s
and after that the dollar sign$
is used to find the end of the line.
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:
- The regex starts with
url:
, followed by\s
to detect whitespace. - After that the opening square bracket is escaped.
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:
- The regex
\w{3}: \d{4}
follows the way cleaning data is added to the masterlist. - First exactly three characters are searched through
\w{3}
which in the masterlist in this context can be eitheritm
,udr
ornav
, after which a colon:
follows. - After that an exactly four digit long number is searched (including a leading whitespace) through
\d{4}
. In this exampleitm: 2733
has been found.
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:
- All Creation Club plugin filenames start with
cc
followed by a set of three varying characters from the Latin alphabet. The regular expression to match these three characters is\w{3}
. - After that all Creation Club plugins for Skyrim Special Edition include
sse
in their filenames, followed by exactly three digits from the range 0 to 9. The regular expression for that issse\d{3}
. - For the Fallout 4 Creation Club plugins the next set of characters ist
fo4
in most cases, and in minority of cases it isf04
, followed by exactly three digits from the range 0 to 9. The regular expression for that isfo4\d{3}
, though this expression will not find the ones withf04
. - After the three digits follows a hyphen
-
(or in a minority of cases, an underscore_
) followed by a descriptive string such asbackpacks
orpipmystery
. Our regex isn't interested in that part however, as it isn't really necessary in order to find the Creation Club plugins - it's good enough already. - As a more general approach,
cc\w{6}\d{3}
could also be used, and this variation should find all Creation Club plugins from both Skyrim Special Edition and Fallout 4. - You could generalise it even more to
cc\w{9}
as\w
in addition to characters from the latin alphabet & the underscore also finds digits. However, this approach would also easily find false positives such askonahrik_accoutrements.esp
.
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:
- Finds most occurrences, taking advantage of the expected indentation of such elements & how it will be preceded by a colon & newline & followed by a less indented line.
- The regex starts with
: *\r?\n
to find a colon:
after which a whitespace and the asterisk*
follow to indicate zero or more whitespaces after the colon. After that\r?\n
is used to find an immediately following end of the line. This is done so that for exampleafter:
can be matched, after which then the potential single-element list could follow in the next line. - The next step is to find a hyphen
-
in the next line of text using{3,}-
. For this we use a whitespace followed by the quantifier{3,}
which as such searches three or more whitespaces, followed by the hyphen-
. - After that we continue with
.*
to find zero or more of characters the non-escaped period (any character except line break) may find after the hyphen (e.g.'TheChoiceIsYours.esp'
) and follow that up with\r?\n
to find the end of the second line. - The final step is to use
{2,4}(?! )
for what comes after the single-element lists. First we use{2,4}
to indicate two to four whitespaces followed by a negative lookahead(?! )
to rule out any matches with additional whitespaces in this line. Aclean
tag indented by four spaces would fulfill this check.
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+)
{2,4}(?! )
has been placed inside a capturing group( )
as the first alternative.- Within this capturing group are two alternatives, seperated by the OR operand
|
and the second alternative is\r?\n+
which aim is to find one or more new lines after the second line.
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+)
- Instead of the non-escaped period in
-.*
we now use-[^\r?\n|]*
to exclude the|
character in the next line. - This is achieved through searching one character that is not x with
[^x]
andx
being\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:
- Relevant use case: Revisit merger tags for WB v310
- The regex
(\[|-|:)
is meant to be read as(a|b|c)
, so as a capturing group( )
where three alternatives are seperated with the OR operand|
. - In this example,
a
would be the escaped opening square bracket[
,b
would be a hyphen-
andc
would be the colon:
- After the capturing group and before the other tags follows a whitespace and an asterisk
*
to search for zero or more whitespaces. - Another capturing group
(Actors\.Perks|Invent|Outfits|(R\.)?Relations|Derel)
is used to search for the different tags that should be reevaluated at a later date.
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:
- Relevant use case: Revisit mods with NoMerge tag for WB v311+
- The regex
(\[|-|:)
is meant to be read as(a|b|c)
, so as a capturing group( )
where three alternatives are seperated with the OR operand|
. - In this example,
a
would be the escaped opening square bracket[
,b
would be a hyphen-
andc
would be the colon:
- After the capturing group and before the NoMerge tag follows a whitespace and an asterisk
*
to search for zero or more whitespaces.
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:
- This regex is able to easily replace
.esp
file extensions to.esl
.
Replace Invent Bash Tag
Find:
\s{6}-\sInvent$
Replace:
- Test
Summary:
- Replaces the Bash Tag
Invent
withTest
. - While searching for whitespaces can be done with the regular expression
\s
, replacing them must be done the normal way. - This means that any number of whitespaces that have been found through a regex (e.g.
\s{6}
), must be typed individually within the Replace field. - The end of the line is detected with the dollar sign
$
.
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:
\d{1,}
is used to detect one or more digits, to match the mod page number in the link, e.g.71404
.- This expression is then placed within a capturing group
( )
, so that the Replace Field has access to it. - After the capturing group comes an apostrophe
'
to detect the end of the link that has no trailing slash. \1
in the Replace field copies the contents of the first capturing group over from the Find field (in this case there is only one).- As the last step comes
/'
after\1
to add the trailing slash.
Update location data to include a name
Find:
\s{4}url: \[\s(.*)\s\]
Replace:
url:\r\n - link: \1\r\n name: ''
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:
- Any whitespaces have been added individually within the Replace field.
\1
in the Replace field copies the contents of the first capturing group over from the Find field (in this case there is only one).