クラス名っぽい名前を変数名っぽい名前に変換する。

re.scannerを使った。

こんな変換

  • FooBar -> foo_bar
  • XYBox -> xy_box
import re

class ClassNameToVarName(object):
    scanner = re.Scanner([
            (r'^[A-Z]+?(?=[A-Z][^A-Z])', lambda sc, s: s.lower()), 
            (r'^[A-Z]', lambda sc, s: s.lower()), 
            (r'[A-Z]+', lambda sc, s : "_"+s.lower()), 
            (r'[^A-Z]+', ambda sc, s : s), 
      ])
    
    @classmethod
    def convert(cls, name):
        tokens = cls.scanner.scan(name)[0]
        return "".join(tokens)

to_varname = ClassNameToVarName.convert

test

from nameutils import to_varname
from nose.tools import ok_, eq_

def test_classname_to_varname0():
    return eq_(to_varname("AbcMart"), "abc_mart")

def test_classname_to_varname1():
    return eq_(to_varname("_fAbcMart"), "_f_abc_mart")

def test_classname_to_varname2():
    return eq_(to_varname("ABCMart"), "abc_mart")

def test_classname_to_varname3():
    return eq_(to_varname("XAndY"), "x_and_y")

def test_classname_to_varname4():
    return eq_(to_varname("FooBarBoo"), "foo_bar_boo")

テスト結果。

.....
----------------------------------------------------------------------
Ran 5 tests in 0.001s

OK