Tes3Mod:XStringMatch

A function added by MWSE.

This function allows to perform a Regular Expression (also called R.E. or Regex) check on a string, allowing for very flexible and powerful pattern and string matching/identification. For example, you can check if a string contains certain words, or a certain set of characters, in it and in a specific position and order, if you want, and much more.
:''Note: Up until version v0.9.5-alpha.20150718 of MWSE by Merzasphor, an oversight in this function caused it to allow partial matches, causing undesired matches to successfully occur in certain cases.


Syntax and usage
 
The above performs a case sensitive Regular Expression  match on source using the pattern in pattern. Regular expressions are pattern matching expressions. MWSE uses the Regex library from the Boost C++ library, from  The regular expression style is the Perl syntax; please see the Boost documentation for full documentation. However, here is a partial quick summary:
 
.	Matches any one character.
^	Matches the beginning of the string.
$	Matches then end of the string.
( and )	Groups a sub-expression (see below).
Makes the preceeding item or group match zero or more times.
?	Makes the preceeding item or group match zero or once.
+	Makes the preceeding item or group match one or more times.
{integer}	Makes the preceeding item or group match exactly integer times.
{int1,int2}	Makes the preceeding item or group match from int1 to int2 times.
|	Alternation; makes the pattern match either the item on the left of the | or the item on the right.
[character set]	Matches a single character from the set character set. The set can contain individual characters, or ranges of the form a-b, which matches all characters between a and b, including a and b. (For example, [A-Z] will match upper case letters.) If the character set begins with ^, then it will match any character except those in the character set.
:name:	Matches a single character from the pre-defined set name.
\character	Matches the character; that is, removes the special meaning, if any, from character. (For example, "." matches any single character, but "\." matches the period character.)
\d	Match a digit (0-9).
\l	Match a lower case letter (a-z).
\s	Match whitespace (space, tab).
\u	Match an upper case letter (A-Z).
\w	Match a word (a string of letters, digits, and underscores)
\D	Match anything but a digit.
\L	Match anything but a lower case letter (a-z).
\S	Match anything but whitespace (space, tab).
\U	Match anything but an upper case letter (A-Z).
\W	Match anything but a word.
\ 
This function will return the value 1 if a successful match was made, or the value 0 otherwise.

More regular expression syntax info and examples may be found at the Perl documentation, but note that that page can be more technical and some parts in it contain actual Perl language syntax as well, which a reader that does not know Perl may not grasp. You may want to try the Boost documentation (linked above), first.
Examples

Example 1: simplest example
The simplest use of this function is to test whether a string contains another string anywhere within it:
 
match will be 1 if the name of someNPC has the text "Guard" anywhere within it (so among the names that will be matched are "Guard", "Hlaalu Guard", "Imperial Guard Sharpshooter", and even "CoolGuardsman").

Example 2: case insensitivity (ignore letter case) and more
This example set shows how to use case insensitivity, word matching and alternation (essentially an OR operator).

Changing the previous example to only match whole words (so it no longer matches "Guardsman") looks like this:
 setx match to xStringMatch name "\ 
You can leave out the \>'' part and it will then be able to match "Guardsman", but still won't match "CoolGuardsman".

By default, all matches are case sensitive. As detailed in the quick summary above, this can be turned off via a special expression:
 

The alternation operator | can be used to match either one of its two sides (it's essentially an OR operator). Here are the previous examples modified to match Ordinators as well:
 setx match to xStringMatch name "(?i)Guard|Ordinator" ;case insensitive
setx match to xStringMatch name "(?i)\ 

Example 3: detect guildhalls
The cell names of Mages Guild and Fighters Guild halls vary according to the city they are in, and in Wolverine Hall they use a different format.
The example script below will display a message whenever the player enters any MG or FG guildhall. It will also detect the cell change no matter how it occurs, so it will detect any kind of player teleportation and transportation just fine, including guild guide and scripting/console commands (such as coc).
 begin matchtest
;When the PC enters a new cell, it will check to see if it
;is either a Mage's or Fighter's guildhall.  If so, the PC will be greeted.
short framecount
long prev_cell
long cell
long temp

;don't run every frame
set framecount to ( framecount + 1 )
if ( framecount  
The xStringMatch call in this script can also be written in the following ways - they are all exactly equivalent:
 

Example 4: detect a diverse set of items
The example script will check the ID of the item (or any other entity) the player's cursor is pointed at, and will trigger a message if it matches any one condition out of a varied condition set. Specifically, it will trigger for the following item IDs:
Those that are exactly equal to "sc_paper plain" or "daedric_towershield" or "cup" (the last one should never match, unless a mod adds such an item).
Those that begin with "misc_com_".
Those that contain "bowl" anywhere.
 begin matchtest2

short framecount
long pctarget
long temp
long bid

if ( MenuMode ) ;don't run in menus
	return
endif

;don't run every frame
set framecount to ( framecount + 1 )
if ( framecount  

Example 5: wildcards
In a regular expression, the . special character will match any one character. Similarly, there are symbols that function as less general wildcards (for instance they match any digit, any lowercase letter or any word). Combined with the quantifiers *, +, ? and {}, they can be turned into wildcards that match multiple or any number of characters. An optional wildcard that matches any number of characters is created by the .* symbol.
 
Note the above examples will match even if armorid is only a partial match (e.g. the last example will match if armorid is "blackiron_pauldron_left_special"), for an exact match add ^ at the beginning of the expression and $ at its end (like in example 4). 
Note that wildcards aren't the answer to everything in a regular expression, sometimes you may want to use alternation instead, and for example, if you wanted to match filenames ending with ".txt" you would not use the anything-wildcard symbol (like you'd do in a simple Windows file search), you'd just do it like this, with no wildcard:
 
Don't forget that all of the examples shown above are case sensitive, as that is the default!

See Also
xPCCellID 
xRefID 
xMyCellID 
xGetName 
xSetName 
xGetBaseID 
xStringCompare 
xStringLength 
xStringParse 
xStringBuild 
xLogMessage 
xMessageFix