'Format Value' behavior with Unmatched $regexp

I'm going through my classical music collection and adding values for my custom OPUS field. I'd like to be able to use a custom Action to add the Opus number to the Opus field, but only if the opus number exists in the title. Here's the custom action I'm currently using:

Field: OPUS
Format Value: $regexp(%title%,'(.Opu?s?.?\s?)(\d+).',$2)

This works fine, when there is an opus number in the title. However, when there's a regular title like so, this action just assigns the title to the Opus field, instead of leaving it null. Example:

Before Action:
Title = Tragic Overture
Opus = null

After Action:
Title = Tragic Overture
Opus = Tragic Overture

I'd like to be able to use this on all my tracks, without having to visually check if it exists for each track before running my custom action. Is there a way to only perform the replace if the RegEx matches?

The reaction is correct even you (and me in the past) expected otherwise.
Let's amend a littlebit the action for your needs.

  1. Match only Op/opus whole words. your regexp matches unwanted cases like octopus, ops, opu. Add also start/end anchors to be safe.
    $regexp(%title%,'^.*?\bOp(?:us)?\b\.?\s*?(\d+).*?$',$1)</li><li>Handle cases without Opus.

That worked beautifully! I've done some research on that syntax, and it looks like you're essentially forcing a match with the optional statement: |^.*($). If I understand the regex engine, $1 is set to the Opus number if the opus expression matches, but is null (capture group with line anchor) if the optional expression matches. With this method, %title% always gets replaced, whether it has an Opus number in it or not, which gives us the requested functionality. Did I get that right?

Yes, perfectly :-).
We needed to always have a '$1' placeholder, that's why I introduced the |^.*($). So match a null if no Opus variants found..

Thanks for the clarification. I'll post a reply to that stickied "Regular Expressions" thread with my custom actions once I've gotten a workflow figured out for composers with multiple numbering systems, like Beethoven.

I've now got a great set of custom actions defined for Opus numbers that's almost ready. The one sticking point is that I can't figure out what the regex should be for the part before the word "opus". Here's what I'm looking at for examples:

a ) Opus 26, ludwig van beethoven - the song
b ) Sonate n. 14 op. 27, n. 2 in cis-moll
c ) IMSLP243517-beethoven_Op5no2_theblahsymphony

d ) Purple Octopus 5 - Shouldn't Match Song

The following regex matches strings b & c, but doesn't match string a. If I take out the custom character class at the beginning, though, it matches string d. Any ideas?

This works for me ...
TITLE MATCHES "^.[\W-.\s]Op(?:us)?[-.\s]?(\d+).*?$"


Yeah, it matches at the regexpal.com tester, but not other engines or in mp3tag. I came up with a simpler way of matching the stuff before 'opus' by eliminating the custom character class and just using word boundaries. It requires an extra step to replace underscores with another character, but it's a bit cleaner. Thanks, anyway!

When I wrote ...

This works for me ...
TITLE MATCHES "^.[\W-.\s]Op(?:us)?[-.\s]?(\d+).*?$"

... then it works in Mp3tag.
I checked it thrice using your examples.

See there for other inspiration ...


My mistake! I re-tested it using that regex and it came out fine. Thanks for linking to that other thread about opus number handling. That will come in handy :slight_smile: