From 0a69754b1c112235634d3d54078f777f44674925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Mond=C3=A9jar?= Date: Sun, 20 Sep 2020 21:10:54 +0200 Subject: [PATCH] Add split_numbers parameter to underscore function. --- inflection/__init__.py | 13 ++++++++++++- test_inflection.py | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/inflection/__init__.py b/inflection/__init__.py index c18a0b6..d89e63a 100644 --- a/inflection/__init__.py +++ b/inflection/__init__.py @@ -394,7 +394,7 @@ def transliterate(string: str) -> str: return normalized.encode('ascii', 'ignore').decode('ascii') -def underscore(word: str) -> str: +def underscore(word: str, split_numbers: bool = False) -> str: """ Make an underscored, lowercase form from the expression in the string. @@ -403,6 +403,14 @@ def underscore(word: str) -> str: >>> underscore("DeviceType") 'device_type' + If ``split_numbers`` is ``True`` inserts underscores between + numbers and alphabet characters. + + Example:: + + >>> underscore('xyz123', split_numbers=True) + 'xyz_123' + As a rule of thumb you can think of :func:`underscore` as the inverse of :func:`camelize`, though there are cases where that does not hold:: @@ -411,6 +419,9 @@ def underscore(word: str) -> str: """ word = re.sub(r"([A-Z]+)([A-Z][a-z])", r'\1_\2', word) + if split_numbers: + word = re.sub(r"([a-zA-Z])(\d)", r'\1_\2', word) + word = re.sub(r"(\d)([a-z])", r'\1_\2', word) word = re.sub(r"([a-z\d])([A-Z])", r'\1_\2', word) word = word.replace("-", "_") return word.lower() diff --git a/test_inflection.py b/test_inflection.py index 30db6c2..1313c07 100644 --- a/test_inflection.py +++ b/test_inflection.py @@ -125,6 +125,13 @@ ("HTML", "html"), ) +CAMEL_TO_UNDERSCORE_SPLITTING_NUMBERS = ( + ("xyz123", "xyz_123"), + ("xyZ123", "xy_z_123"), + ("xy123z", "xy_123_z"), + ("xy123Z", "xy_123_z") +) + STRING_TO_PARAMETERIZED = ( (u"Donald E. Knuth", "donald-e-knuth"), ( @@ -360,6 +367,14 @@ def test_underscore(camel, underscore): assert underscore == inflection.underscore(camel) +@pytest.mark.parametrize( + ("camel", "underscore"), + CAMEL_TO_UNDERSCORE_SPLITTING_NUMBERS +) +def test_underscore_split_numbers(camel, underscore): + assert underscore == inflection.underscore(camel, split_numbers=True) + + @pytest.mark.parametrize( ("some_string", "parameterized_string"), STRING_TO_PARAMETERIZED