bumpver/src/pycalver/regexfmt.py

76 lines
2.2 KiB
Python
Raw Normal View History

2020-10-03 18:36:56 +00:00
# This file is part of the pycalver project
# https://github.com/mbarkhau/pycalver
#
# Copyright (c) 2018-2020 Manuel Barkhau (mbarkhau@gmail.com) - MIT License
# SPDX-License-Identifier: MIT
2020-10-03 16:44:30 +00:00
import re
2020-10-03 18:36:56 +00:00
import logging
2020-10-03 16:44:30 +00:00
import textwrap
from . import pysix
2020-10-03 18:36:56 +00:00
logger = logging.getLogger("pycalver.regexfmt")
2020-10-03 16:44:30 +00:00
def format_regex(regex: str) -> str:
r"""Format a regex pattern suitible for flags=re.VERBOSE.
>>> regex = r"\[CalVer v(?P<year_y>[1-9][0-9]{3})(?P<month>(?:1[0-2]|0[1-9]))"
>>> print(format_regex(regex))
\[CalVer[ ]v
(?P<year_y>[1-9][0-9]{3})
(?P<month>
(?:1[0-2]|0[1-9])
)
"""
# provoke error for invalid regex
re.compile(regex)
tmp_regex = regex.replace(" ", r"[ ]")
tmp_regex, _ = re.subn(r"([^\\])?\)(\?)?", "\\1)\\2\n", tmp_regex)
tmp_regex, _ = re.subn(r"([^\\])\(" , "\\1\n(" , tmp_regex)
tmp_regex, _ = re.subn(r"^\)\)" , ")\n)" , tmp_regex, flags=re.MULTILINE)
lines = tmp_regex.splitlines()
indented_lines = []
level = 0
for line in lines:
if line.strip():
increment = line.count("(") - line.count(")")
if increment >= 0:
line = " " * level + line
level += increment
else:
level += increment
line = " " * level + line
indented_lines.append(line)
formatted_regex = "\n".join(indented_lines)
# provoke error if there is a bug in the formatting code
re.compile(formatted_regex)
return formatted_regex
def pyexpr_regex(regex: str) -> str:
try:
formatted_regex = format_regex(regex)
formatted_regex = textwrap.indent(formatted_regex.rstrip(), " ")
return 're.compile(r"""\n' + formatted_regex + '\n""", flags=re.VERBOSE)'
except re.error:
return f"re.compile({repr(regex)})"
2020-10-03 18:36:56 +00:00
def regex101_url(regex_pattern: str) -> str:
2020-10-03 16:44:30 +00:00
try:
2020-10-03 18:36:56 +00:00
regex_pattern = format_regex(regex_pattern)
2020-10-03 16:44:30 +00:00
except re.error:
2020-10-03 18:36:56 +00:00
logger.warning(f"Error formatting regex '{repr(regex_pattern)}'")
2020-10-03 16:44:30 +00:00
return "".join(
(
"https://regex101.com/",
"?flavor=python",
2020-10-03 18:36:56 +00:00
"&flags=gmx" "&regex=" + pysix.quote(regex_pattern),
2020-10-03 16:44:30 +00:00
)
)