import re
regex = re.compile(r"[^\\](?:(?:\\{2})*)\$(?:(?:[=|-]?([A-Z0-9_]*[A-Z_]+[A-Z0-9_]*)|(?:{[=|-]?([A-Z0-9_]*[A-Z_]+[A-Z0-9_]*)})))")
test_str = ("${HAVE_ERROR}\n"
"\\\\${PATH}\n"
"\\\\$SHELL\n"
"\\\\\\\\${PATH}\n"
"${HTTP_PORT}\n"
"$HTTP_PORT\n"
"$PORT\n"
"$1_PORT\n"
"${1_PORT}\n"
"$PORT_345\n"
"${PORT_345}\n"
"${AZK_AGENT_CONF_FILE}\n"
"${HTTP_HOST_2345}\n"
"${=HTTP_HOST_2345}\n"
"${-HTTP_HOST_2345}\n"
"$ENV.HTTP\n\n"
"# ^ should match\n\n"
"# v should not match\n\n"
"any_text\n"
"LIKE_A_ENV_NAME\n"
"\\${PATH}\n"
"\\$SHELL\n"
"\\ \\${PATH}\n"
"\\ \\$SHELL\n"
"\\\\\\${PATH}\n"
"\\\\\\$SHELL\n"
"$1\n"
"${1}\n"
"$@\n"
"$?\n"
"${env}\n"
"${env.io}\n"
"${ENV\n"
"${ENV_hahaha}\n"
"${ENV.HTTP}\n"
"$envs.HTTP_PORT\n"
"${envs.HTTP_PORT}\n"
"${-net.host}\n"
"${-net.port.http}\n"
"${=net.port.http}\n"
"<%azk.default_domain%>\n"
"<%=manifest.dir%>\n"
"#{-system.name}\n"
"#{=manifest.dir}\n"
"#{azk}\n"
"#{azk.io}\n"
"##hello\n"
"$hello\n"
"%hello%\n"
"<hello>")
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