1+ import itertools
12import os
23import re
34import sys
@@ -360,14 +361,8 @@ def pascal_case(word: str) -> str:
360361 return "" .join (items )
361362
362363
363- _snake_case_regex_head = r"[A-Z0-9]"
364- _snake_case_regex_tail = r"[^A-Z0-9]"
365- _snake_case_regex_capital_match = re .compile (
366- rf"({ _snake_case_regex_head } +{ _snake_case_regex_tail } *)"
367- )
368- _snake_case_regex_m_capital_match = re .compile (
369- rf"^({ _snake_case_regex_head } {{1,}})({ _snake_case_regex_head } +{ _snake_case_regex_tail } +)$"
370- )
364+ # Uppercase preceded by a lowercase marks the start of a new camelCase word
365+ _snake_case_regex_camel_match = re .compile (r"(?<=[a-z])([A-Z]+[a-z0-9]*)" )
371366
372367
373368def snake_case (word : str ) -> str :
@@ -376,23 +371,12 @@ def snake_case(word: str) -> str:
376371 >>> snake_case("someWord")
377372 "some_word"
378373 """
379- underscore = "_"
380- no_underscore_words = word .split (underscore )
381- no_underscore_cases : List [str ] = []
382-
383- for w in no_underscore_words :
384- cases = filter (None , _snake_case_regex_capital_match .split (w ))
385- for case in cases :
386- subcases = filter (None , _snake_case_regex_m_capital_match .split (case ))
387- if subcases :
388- for subcase in subcases :
389- no_underscore_cases .append (subcase )
390- else :
391- no_underscore_cases .append (case )
392-
393- snake_word = ""
394- for case in no_underscore_cases :
395- if not case .isdigit ():
396- snake_word += underscore
397- snake_word += case
398- return snake_word .strip (underscore ).lower ()
374+ snake_case_split : List [str ] = word .split ("_" )
375+
376+ camel_case_split : List [str ] = list (
377+ itertools .chain .from_iterable (
378+ filter (None , _snake_case_regex_camel_match .split (w ))
379+ for w in snake_case_split
380+ )
381+ )
382+ return "_" .join (camel_case_split ).lower ()
0 commit comments