import re
regex = re.compile(r"void\s*\*\s*([0-9a-zA-Z\_]*)\s*\[\s*\]\s*\[[0-9a-zA-Z_]*\]\s*=\s*\{(.*?)\}\s*;", flags=re.MULTILINE | re.DOTALL)
test_str = ("/**\n"
" * Link\\'s eyes and mouth textures are placed at the exact same place in adult and child Link\\'s respective object files.\n"
" * This allows the array to only contain the symbols for one file and have it apply to both. This is a problem for\n"
" * shiftability, and changes will need to be made in the code to account for this in a modding scenario. The symbols\n"
" * from adult Link\\'s object are used here.\n"
" */\n"
"#ifndef AVOID_UB\n"
"void* sEyeTextures[PLAYER_EYES_MAX] = {\n"
" gLinkAdultEyesOpenTex, // PLAYER_EYES_OPEN\n"
" gLinkAdultEyesHalfTex, // PLAYER_EYES_HALF\n"
" gLinkAdultEyesClosedfTex, // PLAYER_EYES_CLOSED\n"
" gLinkAdultEyesLeftTex, // PLAYER_EYES_LEFT\n"
" gLinkAdultEyesRightTex, // PLAYER_EYES_RIGHT\n"
" gLinkAdultEyesWideTex, // PLAYER_EYES_WIDE\n"
" gLinkAdultEyesDownTex, // PLAYER_EYES_DOWN\n"
" gLinkAdultEyesWincingTex, // PLAYER_EYES_WINCING\n"
"};\n\n"
"void* sMouthTextures[PLAYER_MOUTH_MAX] = {\n"
" gLinkAdultMouthClosedTex, // PLAYER_MOUTH_CLOSED\n"
" gLinkAdultMouthHalfTex, // PLAYER_MOUTH_HALF\n"
" gLinkAdultMouthOpenTex, // PLAYER_MOUTH_OPEN\n"
" gLinkAdultMouthSmileTex, // PLAYER_MOUTH_SMILE\n"
"};\n"
"#else\n"
"// Defining `AVOID_UB` will use a 2D array instead and properly use the child link pointers to allow for shifting.\n"
"void* sEyeTextures[][PLAYER_EYES_MAX] = {\n"
" {\n"
" gLinkAdultEyesOpenTex, // PLAYER_EYES_OPEN\n"
" gLinkAdultEyesHalfTex, // PLAYER_EYES_HALF\n"
" gLinkAdultEyesClosedfTex, // PLAYER_EYES_CLOSED\n"
" gLinkAdultEyesLeftTex, // PLAYER_EYES_LEFT\n"
" gLinkAdultEyesRightTex, // PLAYER_EYES_RIGHT\n"
" gLinkAdultEyesWideTex, // PLAYER_EYES_WIDE\n"
" gLinkAdultEyesDownTex, // PLAYER_EYES_DOWN\n"
" gLinkAdultEyesWincingTex, // PLAYER_EYES_WINCING\n"
" },\n"
" {\n"
" gLinkChildEyesOpenTex, // PLAYER_EYES_OPEN\n"
" gLinkChildEyesHalfTex, // PLAYER_EYES_HALF\n"
" gLinkChildEyesClosedfTex, // PLAYER_EYES_CLOSED\n"
" gLinkChildEyesLeftTex, // PLAYER_EYES_LEFT\n"
" gLinkChildEyesRightTex, // PLAYER_EYES_RIGHT\n"
" gLinkChildEyesWideTex, // PLAYER_EYES_WIDE\n"
" gLinkChildEyesDownTex, // PLAYER_EYES_DOWN\n"
" gLinkChildEyesWincingTex, // PLAYER_EYES_WINCING\n"
" },\n"
"};\n\n"
"void* sMouthTextures[][PLAYER_MOUTH_MAX] = {\n"
" {\n"
" gLinkAdultMouthClosedTex, // PLAYER_MOUTH_CLOSED\n"
" gLinkAdultMouthHalfTex, // PLAYER_MOUTH_HALF\n"
" gLinkAdultMouthOpenTex, // PLAYER_MOUTH_OPEN\n"
" gLinkAdultMouthSmileTex, // PLAYER_MOUTH_SMILE\n"
" },\n"
" {\n"
" gLinkChildMouthClosedTex, // PLAYER_MOUTH_CLOSED\n"
" gLinkChildMouthHalfTex, // PLAYER_MOUTH_HALF\n"
" gLinkChildMouthOpenTex, // PLAYER_MOUTH_OPEN\n"
" gLinkChildMouthSmileTex, // PLAYER_MOUTH_SMILE\n"
" },\n"
"};\n"
"#endif\n\n"
"Color_RGB8 sTunicColors[PLAYER_TUNIC_MAX] = {\n"
" { 30, 105, 27 }, // PLAYER_TUNIC_KOKIRI\n"
" { 100, 20, 0 }, // PLAYER_TUNIC_GORON\n"
" { 0, 60, 100 }, // PLAYER_TUNIC_ZORA\n"
"};\n\n"
"Color_RGB8 sGauntletColors[] = {\n"
" { 255, 255, 255 },\n"
" { 254, 207, 15 },\n"
"};\n\n"
"Gfx* sBootDListGroups[][2] = {\n"
" { gLinkAdultLeftIronBootDL, gLinkAdultRightIronBootDL }, // PLAYER_BOOTS_IRON\n"
" { gLinkAdultLeftHoverBootDL, gLinkAdultRightHoverBootDL }, // PLAYER_BOOTS_HOVER\n"
"};\n")
matches = regex.finditer(test_str)
for match_num, match in enumerate(matches, start=1):
print(f"Match {match_num} was found at {match.start()}-{match.end()}: {match.group()}")
for group_num, group in enumerate(match.groups(), start=1):
print(f"Group {group_num} found at {match.start(group_num)}-{match.end(group_num)}: {group}")
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Python, please visit: https://docs.python.org/3/library/re.html