The (?-s) syntax, beginning the regex, ensures that any dot will match a single standard character, only and NOT an End of Line character

Then the part <p[^<>\r\n]* looks for the string <p, followed by a range, even null, of characters, different from <, >, \r and \n, till, either, each part of the alternative sequence (....|....|....) :

The string class="fred", beginning with a space character. As this string is preceded by the \K syntax, this means that the regex engine position is reset and that everything matched before that string is forgotten. So, this whole string will be deleted, during the replacement phase

The string class=".+\K fred, beginning with a space which contains a non-null range of standard characters, till the string fred, preceded by a space. Again, due to the \K form, this later string will be deleted

The string class="\Kfred ), beginning with a space and ending with the string fred and a space character. Again, because of the \K syntax, only the string fred and the space character, will be suppressed, during replacement

If you don’t want to repeat the word Fred, several times in the search regex, here is a second solution :

Remember that the (?n) syntax, called a subroutine call, represents the regex enclosed in the nth pair of round brackets, when going through the regex, from left to right and can be placed after of before the group to which it refers !

In our example, the regex is, simply, the string fred and the (?2) forms are located after the second group (fred)

It’s very important to note that the similar regex, which uses back-references, does not work ! Indeed, the regex :

Why ? Well, these positive matchs concern the first case of the alternative. When it tries to match the two other cases of the alternative ( " class=".+\K \2" or " class="\K\2 " ) the group 2 does not exist, as the first part of the alternative is not used !!