Script to perform multiple Regular Expressions


It's fairly common to want to apply several regular expressions to a filename, one after another.

While you can do this using several Rename commands in a row, that isn't ideal. Using multiple Rename commands would means you could not save the operation as a Rename Preset to use from the Rename Dialog. It is also slower as each would be renamed multiple times (once per Rename command), instead of calculating the final name of each file and renaming it once.

Instead of using multiple Rename commands, we use a rename script.

Background reading

Example rename presets

Attached are rename presets which contain the example scripts, which you can use as starting points. These are the basis for the rest of the post.

The versions of the script for Opus 12 & above are slightly better, but use features which will not work with earlier versions.

What the rename script does

Each preset has a script which does approximately the same thing, for different scripting languages or versions of Opus.

Each script, as it is, doesn't do anything very useful. The point is that it's a simple demonstration that you can adapt to do whatever you need.

Each script will do this:

  • Convert the filename to lowercase. (Using the LCase in VBScript or toLowerCase in JScript.)
  • Uppercase any occurrences of the word 'ms'. (Using the respective RegExp objects in each language.)
  • Uppercase any occurrences of the word 'xp'. (Ditto.)
  • Convert the word "windows" to "Windows". (Ditto. Not done by the old Opus 11 version.)

The first two conversions are done case-sensitive, while the final one is case-insensitive (not that it really matters in the example, as the whole string is converted to lower-case first).

Opus 12 JScript:

Opus 12 VBScript:

RegExp syntax in JScript and VBScript

The syntax of regular expressions differs slightly between Opus and JScript/VBScript. (Sadly, there is no one standard regexp syntax and you'll find differences between almost any pair of tools.) In particular, the replacement strings use $1, $2, etc. in both scripting languages, instead of the \1, \2, etc. used in Opus.

A simple example

This thread has a simple, real-world example of a similar multi-regex script being used to solve a slightly different problem.

A more complex example

Another thread, Help needed, Spliting filenames into folders, uses a rename script which based on this one but with conditional branching to solve a more complex/esoteric problem.

Replacing multiple matches with a single expression:

Here is an aspect of regular expressions I had not noticed when first writing this example. Even in 'global' mode, a regexp will not repeatedly/recursively apply the regexp to replace multiple occurrences of something if the pattern matches the entire string.

For example, this only replaces one %20 with a space:

re.Pattern = "(.*)%20(.*)"
str = re.Replace(str, "$1 $2")

To replace all %20 with spaces, you have to use an expression with a smaller scope, like this:

re.Pattern = "%20"
str = re.Replace(str, " ")

(This is different to the special # syntax you can add to the end of a regular expression in the Opus rename dialog. The # at the end is an Opus-specific addition to the standard regexp syntax, and will make Opus apply the expression over and over until either the string stops changing or it starts generating a loop of results which have already been seen.)


Thread has been updated for Opus 12, and tidied up a bit.

Things that were covered in replies have been merged into the main post, or included in the new/updated how-to posts it now links to.

1 Like

Root post has been updated:

  • Now has examples in both JScript and VBScript.
  • Extended the scripts to show examples of case-insensitive matching.

(The legacy Opus 11 example has been left as-is, as it's too time consuming to test changes to that, but the same regex etc. techniques should work fine with both 11 and 12. The main difference between the Opus 11 and 12 scripts is how they split the filename stem from its extension, which hasn't changed.)