Skip to content

Commit 7f94a73

Browse files
authored
camelCase to snake_case conversion - Fixes #9726 (#9727)
* First commit camel case to snake case conversion algorithm, including numbers * code modified to not use regex
1 parent 5869fda commit 7f94a73

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

strings/camel_case_to_snake_case.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
def camel_to_snake_case(input_str: str) -> str:
2+
"""
3+
Transforms a camelCase (or PascalCase) string to snake_case
4+
5+
>>> camel_to_snake_case("someRandomString")
6+
'some_random_string'
7+
8+
>>> camel_to_snake_case("SomeRandomStr#ng")
9+
'some_random_str_ng'
10+
11+
>>> camel_to_snake_case("123someRandom123String123")
12+
'123_some_random_123_string_123'
13+
14+
>>> camel_to_snake_case("123SomeRandom123String123")
15+
'123_some_random_123_string_123'
16+
17+
>>> camel_to_snake_case(123)
18+
Traceback (most recent call last):
19+
...
20+
ValueError: Expected string as input, found <class 'int'>
21+
22+
"""
23+
24+
# check for invalid input type
25+
if not isinstance(input_str, str):
26+
msg = f"Expected string as input, found {type(input_str)}"
27+
raise ValueError(msg)
28+
29+
snake_str = ""
30+
31+
for index, char in enumerate(input_str):
32+
if char.isupper():
33+
snake_str += "_" + char.lower()
34+
35+
# if char is lowercase but proceeded by a digit:
36+
elif input_str[index - 1].isdigit() and char.islower():
37+
snake_str += "_" + char
38+
39+
# if char is a digit proceeded by a letter:
40+
elif input_str[index - 1].isalpha() and char.isnumeric():
41+
snake_str += "_" + char.lower()
42+
43+
# if char is not alphanumeric:
44+
elif not char.isalnum():
45+
snake_str += "_"
46+
47+
else:
48+
snake_str += char
49+
50+
# remove leading underscore
51+
if snake_str[0] == "_":
52+
snake_str = snake_str[1:]
53+
54+
return snake_str
55+
56+
57+
if __name__ == "__main__":
58+
from doctest import testmod
59+
60+
testmod()

0 commit comments

Comments
 (0)