Python挑战将字符串转换为camelCase



我有一个python挑战,如果给定一个字符串,'_''-'在每个单词之间,如the_big_red_applethe-big-red-apple将其转换为驼峰情况。另外,如果第一个单词是大写的,就保持它是大写的。这是我的代码。我不允许在挑战中使用re库,但是我不知道还能怎么做。

from re import sub
def to_camel_case(text):
if text[0].isupper():
text = sub(r"(_|-)+"," ", text).title().replace(" ", "")
else:
text = sub(r"(_|-)+"," ", text).title().replace(" ", "")
text = text[0].lower() + text[1:]

return print(text)

字分隔符可以是--或_下划线。让我们简化一下,把它们都变成下划线:

text = text.replace('-', '_')

现在我们可以开始写单词了:

words = text.split('_')

有了这个,把它们重新组合起来就很简单了:

text = ''.join(map(str.capitalize, words))

或多啰嗦地,生成器表达式,分配''.join(word.capitalize() for word in words).

我留下第一个字符"作为对读者的练习。


如果你RTFM,你会发现它包含了丰富的知识。https://docs.python.org/3/library/re.html raw-string-notation

"+">

导致结果正则匹配前一个正则的1个或多个重复。ab+将匹配' a '后面跟着任意非零数量的' b '

+的影响都将

  • db_rows_readand
  • db__rows_read

intoDbRowsRead.

,

原始字符串符号("text")使正则表达式保持一致。

你的问题中的正则表达式不完全需要一个原始字符串,因为它没有疯狂标点符号像backwhacks。但这是一个很好的习惯r-string中的正则表达式,以防万一。你永远不知道什么时候代码维护将附加额外的元素,谁想要一个微妙的正则表达式bug呢?

您可以这样尝试:

def to_camel_case(text):
s = text.replace("-", " ").replace("_", " ")
s = s.split()
if len(text) == 0:
return text
return s[0] + ''.join(i.capitalize() for i in s[1:])

print(to_camel_case('momo_es-es'))

print(to_camel_case('momo_es-es'))的输出为momoEsEs

r"..."指的是Python中的Raw String,这仅仅意味着将间隙视为文字而不是转义字符。

(_|-)[+]Regular Expression,匹配包含一个或多个-_字符的字符串。

  • (_|-)表示匹配包含-_的字符串。
  • +表示匹配上述字符(-_)多于在字符串中出现一次或多次。

如果你不能使用re库来解决这个问题:

def to_camel_case(text):
# Since delimiters can have 2 possible answers, let's simplify it to one.
# In this case, I replace all `_` characters with `-`, to make sure we have only one delimiter.
text = text.replace("_", "-") # the_big-red_apple => the-big-red-apple

# Next, we should split our text into words in order for us to iterate through and modify it later.
words = text.split("-") # the-big-red-apple => ["the", "big", "red", "apple"]
# Now, for each word (except the first word) we have to turn its first character to uppercase.
for i in range(1, len(words)):
# `i`start from 1, which means the first word IS NOT INCLUDED in this loop.
word = words[i]

# word[1:] means the rest of the characters except the first one
# (e.g. w = "apple" => w[1:] = "pple")
words[i] = word[0].upper() + word[1:].lower()
# you can also use Python built-in method for this:
# words[i] = word.capitalize()
# After this loop, ["the", "big", "red", "apple"] => ["the", "Big", "Red", "Apple"]
# Finally, we put the words back together and return it
# ["the", "Big", "Red", "Apple"] => theBigRedApple
return "".join(words)

print(to_camel_case("the_big-red_apple"))

试试这个:

  • 首先,将所有分隔符替换为一个,即str.replace('_', '-')
  • str.split('-')标准分隔符
  • 上分割字符串
  • 将列表中的每个字符串大写,即str.capitilize()
  • str.join
  • 连接大写字符串
>>> s = "the_big_red_apple"
>>> s.replace('_', '-').split('-')
['the', 'big', 'red', 'apple']
>>> ''.join(map(str.capitalize, s.replace('_', '-').split('-')))
'TheBigRedApple'
>> ''.join(word.capitalize() for word in s.replace('_', '-').split('-'))
'TheBigRedApple'

如果第一个字符需要小写,则:

>>> camel_mile = lambda x: x[0].lower() + x[1:]
>>> s = 'TheBigRedApple'
>>> camel_mile(s)
'theBigRedApple'

,

  • 首先将所有分隔符替换为空格str.replace('_', ' ')
  • 标题化字符串str.title()
  • 从字符串中删除空格,即str.replace(' ', '')
>>> s = "the_big_red_apple"
>>> s.replace('_', ' ').title().replace(' ', '')
'TheBigRedApple'

的另一个选择,

  • 遍历字符,然后在前一个字符上保持指针/注释,即for prev, curr in zip(s, s[1:])
  • 检查前一个字符是否为分隔符之一,如果是,将当前字符大写,即curr.upper() if prev in ['-', '_'] else curr
  • 跳过空白字符,即if curr != " "
  • 然后添加第一个小写字符,[s[0].lower()]
>>> chars = [s[0].lower()] + [curr.upper() if prev in ['-', '_'] else curr  for prev, curr in zip(s, s[1:])  if curr != " "]
>>> "".join(chars)
'theBigRedApple'

另一个选择,

  • 将所有分隔符替换为单个分隔符,s.r Replace ('-', '_')
  • 转换为字符列表,list(s.replace('-', '_'))
  • 当字符列表中仍然有'_'时,保留
    • 查找下一个'_'
    • 的位置
    • '_'后面的字符替换为大写的
    • ''代替'_'
>>> s = 'the_big_red_apple'
>>> s_list = list(s.replace('-', '_'))
>>> while '_' in s_list:
...     where_underscore = s_list.index('_')
...     s_list[where_underscore+1] = s_list[where_underscore+1].upper()
...     s_list[where_underscore] = ""
... 
>>> "".join(s_list)
'theBigRedApple'

>>> s = 'the_big_red_apple'
>>> s_list = list(s.replace('-', '_'))
>>> while '_' in s_list:
...     where_underscore = s_list.index('_')
...     s_list[where_underscore:where_underscore+2] = ["", s_list[where_underscore+1].upper()]
... 
>>> "".join(s_list)
'theBigRedApple'

注意:为什么我们需要将字符串转换为字符列表?因为字符串是不可变的,'对象不支持项赋值


顺便说一句,regex解决方案可以利用一些组捕获,例如

>>> import re
>>> s = "the_big_red_apple"
>>> upper_regex_group = lambda x: x.group(1).upper()
>>> re.sub("[_|-](w)", upper_regex_group, s)
'theBigRedApple'
>>> re.sub("[_|-](w)", lambda x: x.group(1).upper(), s)
'theBigRedApple'