Code for filtering within one tag field

I would like to request help with this simple filtering expression

GENRE HAS ##X AND NOT GENRE HAS ##Y

It works in the filter box but I want it to have in form of a column. The values in question start always with double hashtag and consist of digits and / or letters [in case of X] and only digits [in case of Y]

I think it could go something like this

$if(%GENRE%,

(%GENRE%,'##X\d','##Y\d')
,'OK','ERROR')but I  most certain miss the main part where the code is told to actually search and compare values

Something like: A regular expression is basically matching what you want (a glorified filter) and replacing it with your string in one function for each replace: OK & ERROR.

$regexp($regexp(%genre%,'^##(?i)[a-z]+$','OK'),'^##\d+$','ERROR')

Word of warning, only use in the VALUE field and leave the FIELD (field) empty otherwise it may cause issues overwriting values.

EDIT:
Added to code, to turn on case insensitivity.
(?i)

Thank you

But once again I forgot to precise and did not take into consideration other values that need to be excluded

The correct set of values can be something like these here:

##D1  ##D5  ##22  ##23  ##24  ##35
##D3 ##21 ##37 ##39
##D3 ##31 ##21  ##23         ##D2##D1

So the rule is: every GENRE has to has at least on DX, at last one 2X and at least one 3X; where X is single digit and D is literally the sign for the capital letter d. The pauses shuld be ignored and the ## is always the indicator of a new value

There are also values like

##3M
##56
##81
##9Y
##DESERTbut they have to be left out from the equation

Please be more specific on the starting post. I still don't understand the last one and afraid of my life on how to even go about tackling it. Now I'm confused again.

Can you not just use the filtered expressions that you already use in my regexp that work like you described in the first post. But with HAS you can't. It would have to be MATCHES to use regexp to MATCH them.

What is the existing filter expression you say works?

You say ##22 is a good value but ##81 is not one.

This is some Leonardo Di Vinci stuff you're doing to your tags right here :wink:

Eee...

GENRE HAS ##D AND NOT GENRE HAS ##2

Although it will bring up also cases that have values like ##DUNGEON or ##DESERT which is not correct, but I can menage that just by looking at them [as I have some sorting order applied to the GENRE and every##D variation with a digit should be at the very beginning, with DUNGEON or DESERT residing further down the tag field]

And then [after getting rid of errors] I can use the second step

GENRE HAS ##D AND NOT GENRE HAS ##3or
GENRE HAS ##2 AND NOT GENRE HAS ##3

But the problem with this one is that it will not bring up cases in which GENRE has the ##3 variant in the form of only ##3M [which is not correct because I can't have only ##3M in GENRE without for example ##31 accompanying it]

Yes, that is true. [Well, 81 is also correct value but not when I'm searching for those specific errors concerning single digits following D, 2 or 3; because those three groups are interconnected with each other]

As we can see, when using in Filter Box the expression is very simple, espacially when divided into two steps; but not precise to the very end of the rules

All of this is better of doing in a one-off filter. But I can't get my head around how it can be done in one step. No offense but it seems bonkers and not very user-friendly or managable.

This is just combining your step 1 and two example there.

%genre% MATCHES "##D\d+$|##\d+$"
##D\d+$ will match ##D{any digit character until the end of string} | in regexp terms mean OR expression ##\d+$ will match ##{any digit character until the end of string}

It's how you combine these I'm not sure about!

The inverse of the above is.
NOT %genre% MATCHES "##D\d+$|##\d+$"

You want to create a formatstring expression, which gives a result value, which can be displayed in a Mp3tag list view cell.

A regexp match can be simulated by ...

$ifgreater($strstr(%GENRE%,'##D'),0,'YES','NO')
... for example a match gives 'YES' ...

... or ...
$ifgreater($strstr(%GENRE%,'##2'),0,'YES','NO')
... for example a match gives 'NO' ...

... or ...
$add($ifgreater($strstr(%GENRE%,'##D'),0,1,0),$ifgreater($strstr(%GENRE%,'##2'),0,1,0))
... here a result of less than 2 shows that at least one case is not true.

DD.20170707.1248.CEST

I am beginning to think, no offense intended and thank for your help, that I should have stuck with those simple filter expressions of mine; divided into steps

The amount of time that I already used up on those attempts of translating them to columns will never pay of, because they will be used [at most] only a few times a year

This work, thank you. But...

First to wrap a head around the problem with it and my overall rules let us name the column with this code "D&2". Such name will in the future clearly suggest to me that I am looking for cases where there is

##Dxand    ##2xwhere the >>x<< is a single digit. And so such named column with that code when displaying

0 - tells me that I am missing 2 ingredients, because none is present
1 - tells me that I am missing 1 ingredient, because 1 is present
2 - tells me that everything is OK, because there are 2 out of 2 ingredients

[And also I would be using column "D&3" or "2&3"]

And so now:

1] How do I replace

with

?

If there is ##DESERTsomewhere in the GENRE tag then using '##D'will show false results, reading up and counting ##DESERTthe same way as it would look at ##D1or ##D4

2] This code will label as errors cases like

2A]
a completely empty GENRE tag field; in a file that hasn't been yet evaluated [tagged]

2B]

##00or any other sign used an indicator of a evaluated ["tagged"] file [that did not get a real data input into GENRE tag]

2C]

##55
##56 ##57    ##90
##99  ##ACTION
##TENSION ##ACTIONor any other proper values, that have nothing to dot with the Dx / 2x / 3x group [where >>x<< is a single digit]

If you've say 3 different scenarios, why not set up 1 column for each?

Same on my side.

You can try this formatstring ...
$ifgreater($len(%GENRE%),$len($regexp(%GENRE%,'##(D|)\d+',)),1,0)

DD.20170714.1157.CEST

But I will, if the code will be working

But if you suggesting to keep D's in one column [separate tag field], 2's in second and 3's in third and somehow compare them- then this would be most inconvenient. Because on column could have from 1 to 7 values and so I would have to have 3 columns set to a width accommodating such possibilities. And that would take something like half of my screen [and then I would also have the rest of GENRE displayed]

Unfortunately it does not work

I think we should stop. Than you both for your time

I will revert now to the simple filter box filtering. I have managed to upgrade those 2 steps of mine into a single one while at the same time averting issues with ##DESERT and such

((GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND NOT GENRE HAS ##2)
OR
((GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND NOT GENRE HAS ##3)
OR
((NOT GENRE HAS ##D1 OR NOT GENRE HAS ##D2 OR NOT GENRE HAS ##D3 OR NOT GENRE HAS ##D4) AND GENRE HAS ##2)
OR
((NOT GENRE HAS ##D1 OR NOT GENRE HAS ##D2 OR NOT GENRE HAS ##D3 OR NOT GENRE HAS ##D4) AND GENRE HAS ##3)I have tested it and it gives me exactly what I need and does not show false errors

But if someone thinks has the ability to translate this to a single expression suitable for a column, then please do give it a try

It looks like as if you want to handle two cases, right?

A:
(GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND NOT (GENRE HAS ##2 OR GENRE HAS ##3)
... gives result: ##D1, ##D2, ##D3, ##D4

B:
NOT (GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND (GENRE HAS ##2 OR GENRE HAS ##3)
... gives result: ##2, ##3

DD.20170714.1806.CEST

Five cases; six to be precise

Because five most often possible errors in my system are [where >>x<< is a single digit number]:
##Dx is present - and nothing else
##Dx is present and ##2x is present - but not ##3x
##Dx is present and ##3x is present - but not ##2x
##3x is present - and nothing else
##2x is present and ##3x is present - but not ##Dx

[and by "nothing else" I do not mean here at this point other numbers like "55" or words like "dungeon", as they may or may not be present but should not be taken into equation]

And as it turns out my code worked only on simple test cases; but does not work on real life files with many various values in the GENRE tag. The correct code is this:

((GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND (NOT GENRE HAS ##2))
OR
((GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND (NOT GENRE HAS ##3))
OR
((GENRE HAS ##3) AND (NOT GENRE HAS ##2))[And yes there is another sub-rule / reason why in the last line I use "3" and then as a negative I use "2" and why I did not list "<b>##2x is present - and nothing else</b>"]

But for completion it should also include a sixth rare kind of error where there is a word after ## but none of the values listed at the top of this post are present. This little filtering code helps

GENRE MATCHES ##\D+$but it only shows some of the cases based on I do not know what; and most surely goes bonkers when is added to first bigger code
(
((GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND (NOT GENRE HAS ##2))
OR
((GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND (NOT GENRE HAS ##3))
OR
((GENRE HAS ##3) AND (NOT GENRE HAS ##2))
)
AND
(GENRE MATCHES ##\D+$)

[And by rare I mean that it is possible for me to spot that error in Mp3tag, which is not likely to happen in case of those first five errors]

So how do I add that six kind of error to those five?

  1. ##Dx is present - and nothing else
    (GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND NOT (GENRE HAS ##2 OR GENRE HAS ##3)
    ... gives result: ##D1, ##D2, ##D3, ##D4

  2. ##2x is present and ##3x is present - but not ##Dx
    NOT (GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND (GENRE HAS ##2 OR GENRE HAS ##3)
    ... gives result: ##2, ##3

  3. ##3x is present - and nothing else
    NOT (GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4 OR GENRE HAS ##2) AND (GENRE HAS ##3)
    ... gives result: ##3

  4. ##Dx is present and ##2x is present - but not ##3x
    (GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND (GENRE HAS ##2x) AND NOT (GENRE HAS ##3)
    ... gives result: ##D1, ##D2, ##D3, ##D4, ##2x

  5. ##Dx is present and ##3x is present - but not ##2x
    (GENRE HAS ##D1 OR GENRE HAS ##D2 OR GENRE HAS ##D3 OR GENRE HAS ##D4) AND (GENRE HAS ##3x) AND NOT (GENRE HAS ##2)
    ... gives result: ##D1, ##D2, ##D3, ##D4, ##3x

DD.20170715.0830.CEST

Here is a proposal using filter matches ...

  1. ##Dx is present - and nothing else
    (GENRE MATCHES "##D\d+") AND NOT (GENRE MATCHES "##\d+")
    ... gives result: ##D1, ##D2, ##D3, ##D4

  2. ##2x is present or ##3x is present - but not ##Dx
    NOT (GENRE MATCHES "##(D\d+)") AND (GENRE MATCHES "##(2|3)")
    ... gives result: ##2, ##3

  3. ##3x is present - and nothing else
    NOT (GENRE MATCHES "##D\d+") AND (GENRE MATCHES "##3")
    ... gives result: ##3

  4. ##Dx is present and ##2x is present - but not ##3x
    (GENRE MATCHES "##D\d+") AND (GENRE MATCHES "##2") AND NOT (GENRE MATCHES "##3")
    ... gives result: ##D1, ##D2, ##D3, ##D4 with ##2x

  5. ##Dx is present and ##3x is present - but not ##2x
    (GENRE MATCHES "##D\d+") AND (GENRE MATCHES "##3") AND NOT (GENRE MATCHES "##2")
    ... gives result: ##D1, ##D2, ##D3, ##D4 with ##3x

DD.20170716.1325.CEST

Yes, you've got it right

All in all there cannot be #D or #2 or #3 present when not accompanied by the other two; except for that special sixth rule where there can be #2 without both ##D and ##3 but only under the circumstance that there is some ##word. [And all other numbers or empty fields should be ignored]

And it is now that sixth rule that I cannot merge with those first five in one filtering expression for filter box

Hmm, this seems to be your logical system that sticks everything together into one field.
Maybe there is the need to re-organize your line oriented logical system into a system of columns.

DD.20170716.0840.CEST

[So, you went back and edited your post; and I have missed it, because I look always for new ones and expect only grammar / spelling changes in old ones and not whole new sections / codes]

I tested you propositions one by one - and they work, thank you

I also merged all five of them and then added to them solution to the sixth issue, based on what I've already got. Here is the full version, with additional rund brackets for visual purposes:

(((GENRE MATCHES "##D\d+") AND NOT (GENRE MATCHES "##\d+")) OR (NOT (GENRE MATCHES "##(D\d+)") AND (GENRE MATCHES "##(2|3)")) OR (NOT (GENRE MATCHES "##D\d+") AND (GENRE MATCHES "##3")) OR ((GENRE MATCHES "##D\d+") AND (GENRE MATCHES "##2") AND NOT (GENRE MATCHES "##3")) OR ((GENRE MATCHES "##D\d+") AND (GENRE MATCHES "##3") AND NOT (GENRE MATCHES "##2")))

OR

(NOT (GENRE MATCHES "##D\d+") AND NOT (GENRE MATCHES "##2") AND NOT (GENRE MATCHES "##2") AND (GENRE MATCHES "##\D+$"))And so it is now complete [although there is 7th small issue which when touched leads in turn to 8th tiny issue, but that I can deal with by other means; besides: to many steps / issues and one small hypothetical change in the system in future will make such code in need of heavy re-working]

Well, no such need now

But I would not even without that previous code of mine [for 5 errors] and that assembled from yours [for 6 errors], in spite of the fact that I would probably know how to compare such columns and create expression for a column; which was my main goal here at the very beginning. Because it would require more horizontal space [as I aforementioned already] and more of juggling with columns during every day use

And as and ending question: is this code above "translatable" to column expression? If everything that works in filter box is somehow reworkable into a column?

Once there are several columns prepared for all possible cases (1 to 5 or 6 or more) within the Mp3tag list view, and each column is defined for only one specific case, ...
the logical value of "true" could be visualized by the character "1" or by "X", ...
and the logical value of "false" could be visualized by the character "0" or by nothing.

Hmm, it should also be possible to combine all cases into one column, within a big formatstring, ...
to see the results for all cases at once in one column only, ...
to be visualized as e. g. "X_X__X" or as "101001" or as "+-+--+" or as "!?!??!".

DD.20170718.1328.CEST

Examples for "matching":

$iflonger(%GENRE%,$len($regexp(%GENRE%,'##D\d+',)),'match,'no match')
... gives 'match' or 'no match'

$iflonger(%GENRE%,$len($regexp(%GENRE%,'##D\d+',)),1,0)
... gives '1' or '0'

DD.20170718.1444.CEST