2

Below is my code and I was wondering if there was a way to keep caps the way they are?

Such as "num_to_SMS" would still become "numToSMS"?

def to_camel(ident):
  return ''.join(x.capitalize() or '_' for x in ident.split('_'))

print(to_camel('foo'))
print(to_camel('raw_input'))
print(to_camel('num2words'))
print(to_camel('num_to_SMS'))

So far the last example outputs numToSms not numToSMS as desired.

smci
  • 32,567
  • 20
  • 113
  • 146
  • Beside the point, but what's `or '_'` supposed to do? – wjandrea Aug 10 '21 at 02:33
  • I suspect it's simpler to do with a regex using lookbehind assertions to handle preceded by a '_', aithough the `\U` uppercase operator requires extended regex syntax. – smci Aug 10 '21 at 02:49

3 Answers3

1

You could manually uppercase only the first character:

def to_camel(ident):
    return ''.join(x[:1].upper() + x[1:] for x in ident.split('_'))

for s in 'foo', 'raw_input', 'num2words', 'num_to_SMS':
    print(to_camel(s))

Output:

Foo
RawInput
Num2words
NumToSMS

I'm using slices just in case x = ''.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
  • sorry to say, that's not what OP have asked for. See the last line of the post: `So far the last example outputs numToSms not numToSMS as desired.` – devReddit Aug 10 '21 at 11:05
1

Only uppercase the letter directly following the underscore, don't touch anything else, so .capitalize() is paradoxically not the droid you want. Here's the regex approach, based on Making letters uppercase using re.sub:

>>> re.sub('_.', lambda mat: mat.group(0).upper(), 'num_to_SMS')

'num_To_SMS'

(In re.sub, the repl argument can be a function ('callable'), in which case it's passed the Match object mat. We can use this to workaround Python lacking extended regex operators like uppercase \U, which PERL etc. have. There are also third-party Python packages for those.)

smci
  • 32,567
  • 20
  • 113
  • 146
  • sorry to say, that's not what OP have asked for. See the last line of the post: `So far the last example outputs numToSms not numToSMS as desired.` – devReddit Aug 10 '21 at 11:05
0

try:

def to_camel(ident):
    lst = ident.split('_')
    return ''.join(x[:1].upper() + x[1:] if not ((x.isupper() and x.isalpha()) 
    or lst.index(x)==0) else (x if lst.index(x) != 0 else x.lower()) for x in lst)

this code forces to capitalize the first letter of the words if they are not the starting word and are not all capital, and keeps the all capital words as it is if the word is not the starting one.

output:

foo
rawInput
num2words
numToSMS
devReddit
  • 2,696
  • 1
  • 5
  • 20