# What does this say?

A geek friend of mine said that this was what he was listening to and I'm apparently supposed to figure it out:

(?ix)(?![AD-ZC][a-jn-zjm])
(
([[:upper:]])
[[:lower:]]
)
(?=[a-z])
(?!b-z)
(.)
ck
(
(?!\t\r\n\f)
\s
)
(
(?=[A-Z])
(?![A-R])
(?![T-Z])
.\3\2\2\3t
(
(h)
)
)
\4\-\4\5\4\1
(o)
(\8)
d
(?![xa-wz])
[[:alpha:]]\4\5*


Could someone decipher this and tell me what it means? Thanks!

He is listening to

Black Sabbath - Sabbath Bloody Sabbath

I find it hard to explain every step. Basically I used https://regex101.com/r/yM1qV5/1 and looked at the explanation and started filling it in. If you also paste the solution in there as the TEST STRING you see exactly what each capture group is and you can try to understand it. If you're not familiar with regex and are not a 'geek' this might be very hard to understand.

• Got the same thing, 1 min late Jun 30 '15 at 14:52
• Both instances of the letter "L" can be replaced with any other letter and still match :P Jun 30 '15 at 15:35
• Actually a bunch of different things can match due to the way the first two characters are checked and then repeatedly referred to! Jun 30 '15 at 16:03

While the regex pattern isn't perfect at finding only the intended answer (there are a number of variations that the matching string will accept), I'll explain the code and build the answer that Ivo Beckers found.

First an explanation of regex calls that will be important. The pattern matcher moves through the input string, "consuming" characters as it matches them.

(?=__) is a positive lookahead which ensures the next characters match the specification in __; however, unlike normal matching, a lookahead doesn't consume the characters, so they still need to be matched. Conversely, the negative lookahead (?!__) looks ahead and ensures that the next characters don't match __.

When brackets (__) are used around matching statements like __ (but not as part of a lookahead statement), it forms a "capturing group". This means that whatever __ matches to will be stored as a subpattern that can be referred to later, and will be assigned a reference number based on the order of the opening bracket (. For example, if I matched the string abc against the pattern .(.(.)) (. matches almost any single character), then it would match, and the stored subpatterns would be 1:bc and 2:c. Later in the pattern, we can match against these subpatterns \1 and \2.

(?ix)(?![AD-ZC][a-jn-zjm])


(?ix) sets modifiers, which change the behaviour of the pattern matching. i means the pattern matching is case-insensitive. We then have a negative lookahead to check that the next two characters are not [AD-ZC][a-jn-zjm]. This can be a B followed by any character or any character followed by a K or L. They can be non-alphabetical characters, but the next part sorts that out. Let's assume BL so far.

(
([[:upper:]])
[[:lower:]]
)


This matches the first two letters to characters. Since it's on case-insensitive mode, this just makes sure that they're letters, but otherwise it would check that it's an uppercase and a lowercase letter. It also stores the pair as subpattern 1 bl and the first character of the two as subpattern 2 b. Still BL.

(?=[a-z])
(?!b-z)
(.)


We perform a positive lookahead to check that the next character is a letter, followed by a negative lookahead to check that it's not b-z (so it's A). (.) then consumes that character and stores it as subpattern 3 a. BLA

ck


This just matches ck. BLACK

(
(?!\t\r\n\f)
\s
)


The next character is matched to a whitespace character \s but not any of the special whitespace characters. This leaves us with a space '' character stored as subpattern 4. BLACK

(
(?=[A-Z])
(?![A-R])
(?![T-Z])
.\3\2\2\3t
(
(h)
)
)


The three lookaheads assert that the next character is a letter, and not A-R or T-Z, leaving S. . consumes the S, and \3\2\2\3 matches those subpatterns in that order, which is ABBA. This is followed by t and h. The whole group is stored as subpattern 5 SABBATH, and the h is stored as both subpatterns 6 and 7 h. BLACK SABBATH

\4\-\4\5\4\1


This simply matches the numbered subpatterns and the - character, giving - SABBATH BL. BLACK SABBATH - SABBATH BL

(o)
(\8)
d


This matches o and stores it as subpattern 8. It then matches \8 and stores that, too, so subpatterns 8 and 9 are both o. Then it matches d. BLACK SABBATH - SABBATH BLOOD

(?![xa-wz])
[[:alpha:]]\4\5*


Another negative lookahead to ensure that the next character isn't xa-wz, leaving y. [[:alpha:]] then matches the next alphabetical character, which is y. We then add another space with \4, giving us BLACK SABBATH - SABBATH BLOODY. * means to match \5 (SABBATH) 0 or more times, as many times as possible. If we leave it as 0, we're already finished and have a matching pattern, or BLACK SABBATH - SABBATH BLOODY SABBATHSABBATHSABBATHSABBATH is also valid. A quick Google search indicates that "Sabbath, Bloody Sabbath" is a real song, so BLACK SABBATH - SABBATH BLOODY SABBATH seems to be the right answer. Alternatively, he may be listening to zKack saZzatH - SazZATh ZkoOdY!

Interpret the code as a regular expression.
(?=...) Matches if ... matches next, but doesn't consume the string.
(?!...) Matches if ... doesn't match next.
[] Indicates a set of characters

(?ix)(?![AD-ZC][a-jn-zjm]) #Matches 0 or 1 'ix' [rest is unknown]
(
([[:upper:]])
[[:lower:]]
)


I don't know what this would give.

(?=[a-z]) #Which means, any lowercase letter
(?!b-z)   #That isn't between b to z [so 'a']
(.)       #Match any character
ck        #And we get are then given 'ck'


giving us 'a_ck' or 'ack'

(?=[A-Z])   #Any Capital letter
(?![A-R])   #That isn't between A to R
(?![T-Z])   #That isn't between T to Z [So 'S']
.\3\2\2\3t  #Any character with multiple tabs
(h)         #Then we are given h


Which gives us now 'ack'+'Sh'

\4\-\4\5\4\1      #Don't know what this would mean
(o)               #Matches 'o'
(\8)              #Matches an escaped 8, [unknown]
d                 #Given 'd'
(?![xa-wz])       #[unknown]
[[:alpha:]]\4\5*  #[unkown]


Giving us now ('a_ck' or 'ack')+'SH'+'od'

My best guess would be Black Sabbath [from the letters we found]

• Actually some of these parts are modifiers and subpatterns, which refer to other matches in the pattern. Jun 30 '15 at 15:47