9

I would like to check if a string is a camel case or not (boolean). I am inclined to use a regex but any other elegant solution would work. I wrote a simple regex

(?:[A-Z])(?:[a-z])+(?:[A-Z])(?:[a-z])+

Would this be correct? Or am I missing something?

Edit

I would like to capture names in a collection of text documents of the format

McDowell
O'Connor
T.Kasting

Edit2

I have modified my regex based on the suggestion in the comments

(?:[A-Z])(?:\S?)+(?:[A-Z])(?:[a-z])+
Dexter
  • 11,311
  • 11
  • 45
  • 61
  • 2
    It's kind of a difficult thing to determine programatically. Is `camel` camel case? What about `_camel`, `Camel`, `_Camel`, `CONSTCAMEL`, `HTML`, or `var_camelCase`? It's pretty difficult to define unless you know ahead of time what the formatting is. – Silas Ray Apr 16 '12 at 22:39
  • @DavidNehme Not really, I have checked it and my requirements are different/ – Dexter Apr 16 '12 at 22:40
  • @sr2222 What do you mean by formatting? I am looking to capture names like McGauge, LePierre etc in a piece of text. Hope this adds more context. – Dexter Apr 16 '12 at 22:41
  • @mcenley, then specify your requirements? – Qtax Apr 16 '12 at 22:41
  • @mcenley What about O'Connor? – agf Apr 16 '12 at 22:43
  • @Qtax The regex on the link doesn't deal with a boolean function of CamelCase capture but rather a replace of CamelCase to camel_case. I may be wrong here if I didn't understand the question on the dup link correctly. – Dexter Apr 16 '12 at 22:43
  • @agf Yes, I would like to capture those as well. Also something like "T.Mildred" – Dexter Apr 16 '12 at 22:44
  • So this has less to do with CamelCase and more to do with identifying proper names? – Silas Ray Apr 16 '12 at 22:46
  • @sr2222 Ah, yes. The assumption being checking for camel case (along with other "features") would help my task. – Dexter Apr 16 '12 at 22:47
  • So what's wrong with taking any token that starts with a capital letter and contains n other characters? The only real trick there is avoiding other proper nouns and words at the beginning of sentences that aren't names. – Silas Ray Apr 16 '12 at 22:49
  • One would capture strings like 'The','Article' etc. Checking for camel cased names would provide better insights. – Dexter Apr 16 '12 at 22:50
  • But a name like Bill Williams will get by your filter... in any case, what about any token starting with a capital and containing a second capital that is non-contiguous to the first? – Silas Ray Apr 16 '12 at 22:53
  • @sr2222 Yup, you've hit the nail. Is the regex correct? – Dexter Apr 16 '12 at 22:54
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/10141/discussion-between-mcenley-and-sr2222) – Dexter Apr 16 '12 at 22:59
  • 1
    How about some examples of inputs you would like to fail? – William Bettridge-Radford Apr 16 '12 at 23:45

8 Answers8

19

You could check if a string has both upper and lowercase.

def is_camel_case(s):
    return s != s.lower() and s != s.upper() and "_" not in s


tests = [
    "camel",
    "camelCase",
    "CamelCase",
    "CAMELCASE",
    "camelcase",
    "Camelcase",
    "Case",
    "camel_case",
]

for test in tests:
    print(test, is_camel_case(test))

Output:

camel False
camelCase True
CamelCase True
CAMELCASE False
camelcase False
Camelcase True
Case True
camel_case False
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
3

You probably want something more like:

(?:[A-Z][a-z]*)+

Altho that would allow all caps. You could avoid that with:

(?:[A-Z][a-z]+)+

Anchor the expression with ^ and $ or \z if required.

Qtax
  • 33,241
  • 9
  • 83
  • 121
3

Convert your string to camel case using a library like inflection. If it doesn't change, it must've already been camel case.

from inflection import camelize

def is_camel_case(s):
    # return True for both 'CamelCase' and 'camelCase'
    return camelize(s) == s or camelize(s, False) == s
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
1

if you do not want strings starting with upper-case e.g Case and Camelcase to pass True. edit @william's answer:

def is_camel_case(s):
  if s != s.lower() and s != s.upper() and "_" not in s and sum(i.isupper() for i in s[1:-1]) == 1:
      return True
  return False



tests = [
"camel",
"camelCase",
"CamelCase",
"CAMELCASE",
"camelcase",
"Camelcase",
"Case",
"camel_case",
]

for test in tests:
   print(test, is_camel_case(test))

the results:

camel False
camelCase True
CamelCase True
CAMELCASE False
camelcase False
Camelcase False
Case False
camel_case False
Chidi
  • 901
  • 11
  • 15
  • 1
    "CAMELCASE", "Camelcase", and "Case" are valid CamelCase strings. – MattS Dec 29 '22 at 12:08
  • @MattS The question is if that is useful. In many coding styles, 'Case' would be a simple class name, and not a camelcase class or method name. Camel case is useful to distinguish words in a string. 'Camelcase' is also not a very useful identifier. Coming from a google search, Cidis answer is the one that helped me the most. – tm243 Feb 12 '23 at 07:55
0

I think you might get away with just checking that the string has a capital with a lower case letter before it if(line =~ m/[a-z][A-Z]/). Just checking lower and upper fails on the given examples. ~Ben

Ben
  • 669
  • 8
  • 14
0
sub_string= 'hiSantyWhereAreYou'  `Change the string here and try`
index=[x for x,y in enumerate(list(sub_string)) if(y.isupper())] `Finding the index 
of caps`
camel_=[]
temp=0
for m in index:
    camel_.append(sub_string[temp:m])
    temp=m
if(len(index)>0):
    camel_.append(sub_string[index[-1]::])
    print('The individual camel case words are', camel_) `Output is in list`
else:
    camel_.append(sub_string)
    print('The given string is not camel Case')
  • Could you please add some explanation about *how* and *why* your code snippet provides an answer to the question? Thank you. – deHaar Jul 30 '19 at 06:44
0

This regex solution worked for my use case ([A-Z][a-z\S]+)([A-Z][a-z]+)

Tobias P. G.
  • 827
  • 8
  • 15
0

CamelCase

is the practice of writing phrases without spaces or punctuation, indicating the separation of words with a single capitalized letter

def iscamelcase(string):
    non_alpha = [i for i in string if not i.isalpha()]
    substrings= string.translate({ord(i): ' ' for i in non_alpha}).split(' ')
    for string in substrings:
        if not all(char.isupper() for char in string):
            for idx,i in enumerate(string):
                if i.isupper() and idx > 0:
                    return True
    return False
  1. search the string for other signs than charackters and store in non_alpha
  2. replace all non_alpha signs with empty space and split them by empty space to create substrings
  3. Check all substrings to be not fully uppercase and if not the index of the uppercase cant be >0

Output

camel False
camelCase True
CamelCase True
CAMELCASE False
camelcase False
Camelcase False
Case False
camel_case False
Thingamabobs
  • 7,274
  • 5
  • 21
  • 54