以大写字母分割字符串

时间:2010-02-17 00:01:22

标签: python regex string

在给定字符集出现之前分割字符串的pythonic方法是什么?

例如,我想拆分 'TheLongAndWindingRoad' 在任何大写字母出现时(可能除了第一个),并获得 ['The', 'Long', 'And', 'Winding', 'Road']

编辑:它还应拆分单次出现,即 来自'ABC'我想获得 ['A', 'B', 'C']

18 个答案:

答案 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']

感谢。