在给定字符集出现之前分割字符串的pythonic方法是什么?
例如,我想拆分
'TheLongAndWindingRoad'
在任何大写字母出现时(可能除了第一个),并获得
['The', 'Long', 'And', 'Winding', 'Road']
。
编辑:它还应拆分单次出现,即
来自'ABC'
我想获得
['A', 'B', 'C']
。
答案 0 :(得分:111)
不幸的是,Python中的split on a zero-width match是不可能的。但您可以使用re.findall
代替:
>>> import re
>>> re.findall('[A-Z][^A-Z]*', 'TheLongAndWindingRoad')
['The', 'Long', 'And', 'Winding', 'Road']
>>> re.findall('[A-Z][^A-Z]*', 'ABC')
['A', 'B', 'C']
答案 1 :(得分:22)
这是另一种正则表达式解决方案。该问题可以被称为“如何在执行拆分之前在每个大写字母前插入空格”:
>>> s = "TheLongAndWindingRoad ABC A123B45"
>>> re.sub( r"([A-Z])", r" \1", s).split()
['The', 'Long', 'And', 'Winding', 'Road', 'A', 'B', 'C', 'A123', 'B45']
这样做的好处是可以保留所有非空白字符,而其他大多数解决方案都没有。
答案 2 :(得分:17)
>>> import re
>>> re.findall('[A-Z][a-z]*', 'TheLongAndWindingRoad')
['The', 'Long', 'And', 'Winding', 'Road']
>>> re.findall('[A-Z][a-z]*', 'SplitAString')
['Split', 'A', 'String']
>>> re.findall('[A-Z][a-z]*', 'ABC')
['A', 'B', 'C']
如果您希望将"It'sATest"
拆分为["It's", 'A', 'Test']
,请将rexeg更改为"[A-Z][a-z']*"
答案 3 :(得分:6)
@ChristopheD解决方案的变体
s = 'TheLongAndWindingRoad'
pos = [i for i,e in enumerate(s+'A') if e.isupper()]
parts = [s[pos[j]:pos[j+1]] for j in xrange(len(pos)-1)]
print parts
答案 4 :(得分:4)
import re
filter(None, re.split("([A-Z][^A-Z]*)", "TheLongAndWindingRoad"))
或
[s for s in re.split("([A-Z][^A-Z]*)", "TheLongAndWindingRoad") if s]
答案 5 :(得分:3)
src = 'TheLongAndWindingRoad'
glue = ' '
result = ''.join(glue + x if x.isupper() else x for x in src).strip(glue).split(glue)
答案 6 :(得分:2)
替代解决方案(如果您不喜欢显式正则表达式):
s = 'TheLongAndWindingRoad'
pos = [i for i,e in enumerate(s) if e.isupper()]
parts = []
for j in xrange(len(pos)):
try:
parts.append(s[pos[j]:pos[j+1]])
except IndexError:
parts.append(s[pos[j]:])
print parts
答案 7 :(得分:1)
另一个没有正则表达式并且能够在需要时保持连续的大写
...
答案 8 :(得分:1)
使用more_itertools.split_before
工具可以实现这一点。
readAll
它还应该拆分单个事件,即从
import more_itertools as mit iterable = "TheLongAndWindingRoad" [ "".join(i) for i in mit.split_before(iterable, pred=lambda s: s.isupper())] # ['The', 'Long', 'And', 'Winding', 'Road']
我希望获得'ABC'
。
['A', 'B', 'C']
more_itertools
是一个第三方软件包,包含60多个有用的工具,包括所有原始itertools recipes的实现,这样可以避免手动实现。
答案 9 :(得分:0)
使用 enumerate
和 isupper()
<强>代码:强>
strs = 'TheLongAndWindingRoad'
ind =0
count =0
new_lst=[]
for index, val in enumerate(strs[1:],1):
if val.isupper():
new_lst.append(strs[ind:index])
ind=index
if ind<len(strs):
new_lst.append(strs[ind:])
print new_lst
<强>输出:强>
['The', 'Long', 'And', 'Winding', 'Road']
答案 10 :(得分:0)
不使用正则表达式或枚举的替代方法:
word = 'TheLongAndWindingRoad'
list = [x for x in word]
for char in list:
if char != list[0] and char.isupper():
list[list.index(char)] = ' ' + char
fin_list = ''.join(list).split(' ')
我认为如果没有链接太多方法或使用难以阅读的长列表理解,它会更清晰,更简单。
答案 11 :(得分:0)
分享我阅读该帖子时想到的内容。与其他帖子不同。
strs = 'TheLongAndWindingRoad'
# grab index of uppercase letters in strs
start_idx = [i for i,j in enumerate(strs) if j.isupper()]
# create empty list
strs_list = []
# initiate counter
cnt = 1
for pos in start_idx:
start_pos = pos
# use counter to grab next positional element and overlook IndexeError
try:
end_pos = start_idx[cnt]
except IndexError:
continue
# append to empty list
strs_list.append(strs[start_pos:end_pos])
cnt += 1
答案 12 :(得分:0)
先行使用
:在Python 3.7中,您可以执行以下操作:
re.split('(?=[A-Z])', 'theLongAndWindingRoad')
它产生:
['the', 'Long', 'And', 'Winding', 'Road']
答案 13 :(得分:0)
Python方式可能是:
"".join([(" "+i if i.isupper() else i) for i in 'TheLongAndWindingRoad']).strip().split()
['The', 'Long', 'And', 'Winding', 'Road']
对Unicode很有用,避免了re / re2。
"".join([(" "+i if i.isupper() else i) for i in 'СуперМаркетыПродажаКлиент']).strip().split()
['Супер', 'Маркеты', 'Продажа', 'Клиент']
答案 14 :(得分:0)
我认为更好的答案可能是将字符串分成不以大写字母结尾的单词。这样可以处理字符串不是以大写字母开头的情况。
re.findall('.[^A-Z]*', 'aboutTheLongAndWindingRoad')
示例:
>>> import re
>>> re.findall('.[^A-Z]*', 'aboutTheLongAndWindingRoadABC')
['about', 'The', 'Long', 'And', 'Winding', 'Road', 'A', 'B', 'C']
答案 15 :(得分:0)
你可能也想这样做
def camelcase(s):
words = []
for char in s:
if char.isupper():
words.append(':'+char)
else:
words.append(char)
words = ((''.join(words)).split(':'))
return len(words)
输出如下
s = 'oneTwoThree'
print(camecase(s)
//['one', 'Two', 'Three']
答案 16 :(得分:0)
def solution(s):
st = ''
for c in s:
if c == c.upper():
st += ' '
st += c
return st
答案 17 :(得分:-1)
用给定的空格加上字母“L”替换给定的每个大写字母“L”。我们可以使用列表理解来完成此操作,或者我们可以定义一个函数来执行此操作。
In [46]: L = da["c"].plot(label=None)
In [47]: L[0].set_label(None)
如果您选择使用某个功能,请按以下步骤操作。
s = 'TheLongANDWindingRoad ABC A123B45'
''.join([char if (char.islower() or not char.isalpha()) else ' '+char for char in list(s)]).strip().split()
>>> ['The', 'Long', 'A', 'N', 'D', 'Winding', 'Road', 'A', 'B', 'C', 'A123', 'B45']
在给定示例的情况下:
def splitAtUpperCase(text):
result = ""
for char in text:
if char.isupper():
result += " " + char
else:
result += char
return result.split()
但是大部分时间我们用大写字母分割句子,通常情况下我们想要保持通常是连续的大写字母流的缩写。下面的代码会有所帮助。
print(splitAtUpperCase('TheLongAndWindingRoad'))
>>>['The', 'Long', 'A', 'N', 'D', 'Winding', 'Road']
感谢。