我有一个python挑战,如果给定一个字符串,'_'
或'-'
在每个单词之间,如the_big_red_apple
或the-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_read
anddb__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'