# Help with conditional and regex

**URL:** https://community.mp3tag.de/t/help-with-conditional-and-regex/48632
**Category:** Support
**Created:** [April 18, 2020, 5:31pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632 "2020-04-18T17:31:40Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 18, 2020, 5:31pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/1 "2020-04-18T17:31:40Z")

</div>

Hi Taggers,  
after I decided how to manage cover songs, I need a little help writing an Action.  
I am a \*nix user so I know some RegEx, but I need help with MP3tag syntax.

1. `If %title% equals to ".*(.* cover)$" then OriginalArtist=$2`  
($2 should be the second .\* on the regex expression, right?)
2. `If OriginalArtist is not empty and %title% is not ".*cover)$", then %title% = %title% + " (%OriginalArtist% Cover)"`

I'm trying to reach a "one touch" workflow:

1. Use auto-numbering to add TrackNumber (number/total) and DiscNumber (number/total)
2. "Standardize" (to my needs) various info normally put on title (like "featuring","cover","live","acoustic", etc.)
3. Adjust Capitalization (I Love The All Caps Format but I had to fight with roman numbers)
4. TAG -\> Filename (Right now I have two formats to choose if album is one or multi-disc, I will need a little help extracting total discs number and choose the right format automatically)

Maybe I was crazy already...maybe this quarantine gives me too much time to spend on computer 😃

CIAO!

---

<div class="post-metadata">

### Author: ![ohrenkino](https://community.mp3tag.de/user_avatar/community.mp3tag.de/ohrenkino/32/4843_2.png) [@ohrenkino](https://community.mp3tag.de/u/ohrenkino)
#### Post date: [April 18, 2020, 5:37pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/2 "2020-04-18T17:37:39Z")

</div>

> [@Rigido](#):
>
> PS: Some \* disappeared, I don't know why...

Please enclose those code snippets in accent grave (top-left to bottom right) - otherwise it is almost impossible to find the problems if parts of the expression are missing.

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 18, 2020, 5:43pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/3 "2020-04-18T17:43:16Z")

</div>

That is not "real" code, that's why I need help 😉

---

<div class="post-metadata">

### Author: ![ohrenkino](https://community.mp3tag.de/user_avatar/community.mp3tag.de/ohrenkino/32/4843_2.png) [@ohrenkino](https://community.mp3tag.de/u/ohrenkino)
#### Post date: [April 18, 2020, 5:59pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/4 "2020-04-18T17:59:37Z")

</div>

> [@Rigido](#):
>
> `If %title% equals to ".*(.* cover)$" then OriginalArtist=$2`  
> ($2 should be the second .\* on the regex expression, right?)

Ahm no.  
You have to enclose the parts that you want to address with $x in parenthesis.  
If you want to find out if a string is part of another string, use $strstr(), e.g. `$strstr(%title%,"cover")`  
So one could do something like an of the type Action "Format value" for ORIGARTIST  
Format string: `$ifgreater($strstr(%title%,cover),0,$regexp(%title%,.* (.*) cover,$1),)`

> [@Rigido](#):
>
> If OriginalArtist is not empty and %title% is not ".\*cover)$", then %title% = %title% + " (%OriginalArtist% Cover)"

Could be an action of the type "Format value" for TITLE  
Format string: `$ifgreater($strstr(%title%,cover),0,%title%[%origartist% cover],%title%)`

The numbering wizard cannot be called in an action.

> [@Rigido](#):
>
> Adjust Capitalization (I Love The All Caps Format but I had to fight with roman numbers)

You need a separate action following the case adjustment that deals with all the exceptions like the Roman numerals and probably all the "McCoys" and others.

> [@Rigido](#):
>
> TAG -\> Filename

Is an action of the type "Format value" for \_FILENAME where you enter the field variables as format string.  
Please note that you can use the square brackets to hide string parts that may not be filled, e.g. `[CD $num(%discnumber%,1)\]`

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 18, 2020, 7:49pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/5 "2020-04-18T19:49:45Z")

</div>

Wow ohrenkino,  
you gave me so many info, thank you!  
I wrote I'm trying to reach a "workflow" and not a "single click magic wand" action.  
"Capitalization" action reached 18 rows, I will go with this "Original Artist" action.

Thank you

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 10:07am UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/6 "2020-04-19T10:07:30Z")

</div>

Ok, now I have ORIGARTIST:

`$ifgreater($strstr(%title%,' Cover)'),0,$regexp(%title%,'.* \((.*) [Cc]over\)$',$1),)`

but I don't know if I'll use this action before case conversion so I need `strstr` to ignore case or use another function, is it possible?!

---

<div class="post-metadata">

### Author: ![ohrenkino](https://community.mp3tag.de/user_avatar/community.mp3tag.de/ohrenkino/32/4843_2.png) [@ohrenkino](https://community.mp3tag.de/u/ohrenkino)
#### Post date: [April 19, 2020, 10:31am UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/7 "2020-04-19T10:31:22Z")

</div>

you could transform everything into lower case for the initial comparison.  
`$ifgreater($strstr($lower(%title%),' cover)'),0,$regexp(%title%,'.* \((.*) [Cc]over\)$',$1),)`

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 1:23pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/8 "2020-04-19T13:23:20Z")

</div>

With latest regexp information I gave a look at my "Case" group-action and found that I have two actions, one to trim all leading spaces from \_TAG and one for trailing spaces.  
Now I found that there is a $trim function but I can't find the right action to trim all \_TAG. I thought to use "Format value" but can't specify \_TAG.

Any hint?

---

<div class="post-metadata">

### Author: ![ohrenkino](https://community.mp3tag.de/user_avatar/community.mp3tag.de/ohrenkino/32/4843_2.png) [@ohrenkino](https://community.mp3tag.de/u/ohrenkino)
#### Post date: [April 19, 2020, 1:30pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/9 "2020-04-19T13:30:52Z")

</div>

Yes, you have to specify each field. I think that \_TAG is the whole tag data with probably only one leading and one trailing space - if at all.  
You can perform functions that deal with data in a string, though, but not with field boundaries.

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 1:35pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/10 "2020-04-19T13:35:53Z")

</div>

> [@ohrenkino](#):
>
> I think that \_TAG is the whole tag data with probably only one leading and one trailing space

Wait, maybe I didn't understand, are you saying that \_TAG is just one, big string with all tags data and it doesn't mean "every single tag"?! 😮

---

<div class="post-metadata">

### Author: ![ohrenkino](https://community.mp3tag.de/user_avatar/community.mp3tag.de/ohrenkino/32/4843_2.png) [@ohrenkino](https://community.mp3tag.de/u/ohrenkino)
#### Post date: [April 19, 2020, 1:39pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/11 "2020-04-19T13:39:36Z")

</div>

In my understanding the tag is the whole piece of metadata which is attached to a file. E.g. the V1 tag can be found at the end of a file, the V2 tag can be found (mostly) at the beginning.  
The tag itself is then structured into fields.  
You will find a similar naming convention in the help in the overview of supported tag fields.

> **[Tag Field Mappings – Mp3tag Documentation](https://docs.mp3tag.de/mapping/)**
>
> Overview of all available tag fields, their names in Mp3tag, and how they are mapped to the internal structures of the different tag formats. Mp3tag is the universal Tag Editor.

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 1:48pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/12 "2020-04-19T13:48:15Z")

</div>

I think you may be wrong as MP3tag supports \_ALL, \_TAG and \_FILENAME and, from [Actions and batch-operations](https://community.mp3tag.de/t/actions-and-batch-operations/967) tutorial, it looks like \_TAG stands "for every single tag" expect filename, otherwise the example that Dano wrote is useless.  
Don't you think?

---

<div class="post-metadata">

### Author: ![ohrenkino](https://community.mp3tag.de/user_avatar/community.mp3tag.de/ohrenkino/32/4843_2.png) [@ohrenkino](https://community.mp3tag.de/u/ohrenkino)
#### Post date: [April 19, 2020, 2:03pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/13 "2020-04-19T14:03:25Z")

</div>

> [@Rigido](#):
>
> otherwise the example that Dano wrote is useless

The examples perform actions of the type "Replace with regular expression" which is an action that can be used for more or less any string or all characters. The same applies to actions of the type "Case conversion".

But these are actions. The question arose from

> [@Rigido](#):
>
> a $trim function but I can't find the right action to trim all \_TAG

where the problem is that this scripting function produces a string without leading or trailing spaces - and the syntax requires that you either enter a string constant (which would be pointless as while entering, you could leave out the superfluous blanks) or a variable that can produce a (single) string where spaces at the beginning or end can be trimmed.  
I was trying to argue that \_TAG would still produce just one long single string with just one beginning and one end but no separation into fields.  
But I may be wrong.  
To apply scripting functions use actions of the type "Format value".

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 3:25pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/14 "2020-04-19T15:25:55Z")

</div>

> [@ohrenkino](#):
>
> The examples perform actions of the type "Replace with regular expression" which is an action that can be used for more or less any string or all characters.

I think you agree with me that if \_TAG is just one big string that examples (that remove leading and trailing spaces) are at least misleading. I would like to know how many users thought that \_TAG stands for "every single tag", so I just did a test :  
Edited title, artist and album tags adding spaces at the beginning and at the end and run the following action group

![image](https://community.mp3tag.de/uploads/default/original/2X/1/1b1603e19253c3e2ba8f025e7a7c62a29531bdc8.png)

Extra spaces (leading and trailing) are removed from every tag. I think this prove that \_TAG means "every tag".

Said that, do I need two separate actions or can I use the | (pipe) character?

I wrote the following to add "(original artist cover)" to title just if title doesn't contains " cover)" and length of origartist is\>0:

`$if($and($strstr($lower(%title%),' cover)')=0,$len(%origartist%)>0),%title% (%origartist% Cover),%title%)`

But something doesn't work as expected.

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 3:34pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/15 "2020-04-19T15:34:45Z")

</div>

> [@Rigido](#):
>
> I wrote the following to add "(original artist cover)" to title just if title doesn't contains " cover)" and length of origartist is\>0:
> 
> `$if($and($strstr($lower(%title%),' cover)')=0,$len(%origartist%)>0),%title% (%origartist% Cover),%title%)`
> 
> But something doesn't work as expected.

Found it:  
`$if($and($eql($strstr($lower(%title%),' cover)'),0),$grtr($len(%origartist%),0)),%title% (%origartist% Cover),%title%)`

---

<div class="post-metadata">

### Author: ![ohrenkino](https://community.mp3tag.de/user_avatar/community.mp3tag.de/ohrenkino/32/4843_2.png) [@ohrenkino](https://community.mp3tag.de/u/ohrenkino)
#### Post date: [April 19, 2020, 3:39pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/16 "2020-04-19T15:39:40Z")

</div>

> [@Rigido](#):
>
> I think this prove that \_TAG means "every tag".

Still no. You asked about the scripting function $trim() which requires a single string.  
The example is replacing with a regular expression inside a complete string and simply tests "do I find spaces in front of a an end-of-field marker (a binary 0) and if so remove the spaces?" A pattern can be found multple times inside the single \_TAG string and then be treated.  
The example did not use the much more comfortable function $trim() which cuts both, the leading and trailing spaces, for \_TAG.

> [@Rigido](#):
>
> $if($and($strstr($lower(%title%),' cover)')=0,$len(%origartist%)\>0),%title% (%origartist% Cover),%title%)

This has hardly anything to do with the MP3tag scripting functions.  
Please check out the help

> **[Scripting Functions – Mp3tag Documentation](https://docs.mp3tag.de/scripting/#boolean-functions)**
>
> Documentation on Mp3tag's scripting functions. Mp3tag is the universal Tag Editor.

Have a closer look at $eql() and $grtr().  
You can check your expressions in the function Convert\>Tag-Tag

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 4:49pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/17 "2020-04-19T16:49:21Z")

</div>

> [@ohrenkino](#):
>
> Still no. You asked about the scripting function $trim() which requires a single string.  
> The example is replacing with a regular expression inside a complete string and simply tests "do I find spaces in front of a an end-of-field marker (a binary 0) and if so remove the spaces?" A pattern can be found multple times inside the single \_TAG string and then be treated.  
> The example did not use the much more comfortable function $trim() which cuts both, the leading and trailing spaces, for \_TAG.

Now I see your point and I thank you for your patience.

MP3tag uses something like awk does, where you can change RS (record separator, normally a newline) so it should be able to trim leading and trailing spaces from every "record" of one, big string.  
So functions like $trim() rely on "standard/real" strings and some other can handle "big string with different record separator". 🙂

Just to recap initial problem:

1. Now I can extract original artist if title is "Title (OrigArtist Cover)":  
`$ifgreater($strstr($lower(%title%),' cover)'),0,$regexp(%title%,'.* \((.*) [Cc]over\)$',$1),)`
2. If title doesn't show it is a cover and there is an OrigArtist tag, set title accordingly:  
`$if($and($eql($strstr($lower(%title%),' cover)'),0),$grtr($len(%origartist%),0)),%title% (%origartist% Cover),%title%)`

Now I'll work on disc numbers and do the \_filename thing.

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 5:34pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/18 "2020-04-19T17:34:11Z")

</div>

...and:

1. Rename file with "%track% %title%" if single disc, otherwise use "%disc%-%track% %title":  
`$ifgreater($regexp(%discnumber%,'.*/(.*)',$1),1,$num(%discnumber%,1)-$num(%track%,2) %title%,$num(%track%,2) %title%)`

Not a "magic wand" but we are almost there 😃

Ciao.

---

<div class="post-metadata">

### Author: ![ohrenkino](https://community.mp3tag.de/user_avatar/community.mp3tag.de/ohrenkino/32/4843_2.png) [@ohrenkino](https://community.mp3tag.de/u/ohrenkino)
#### Post date: [April 19, 2020, 5:37pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/19 "2020-04-19T17:37:51Z")

</div>

> [@Rigido](#):
>
> use "%disc%-%track% %title":

You could shorten the whole thing to:  
`[$num(%discnumber%,1)-]%track% %title%`  
The square brackets enclose optional parts that only get used if the included field has a value.

---

<div class="post-metadata">

### Author: ![Rigido](https://community.mp3tag.de/user_avatar/community.mp3tag.de/rigido/32/8725_2.png) [@Rigido](https://community.mp3tag.de/u/Rigido)
#### Post date: [April 19, 2020, 5:46pm UTC](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632/20 "2020-04-19T17:46:07Z")

</div>

> [@ohrenkino](#):
>
> You could shorten the whole thing to:  
> `[$num(%discnumber%,1)-]%track% %title%`  
> The square brackets enclose optional parts that only get used if the included field has a value.

Good to know it, but %discnumber% will always have a value (1/1).  
I want to use it just if track is from a multi-disc album.

Ciao.

[Next page](https://community.mp3tag.de/t/help-with-conditional-and-regex/48632.md?page=2)
