주어진 문자 집합이 발생하기 전에 문자열을 분할하는 비단뱀적인 방법 은 무엇입니까 ?
예를 들어, 'TheLongAndWindingRoad'
대문자 (아마도 첫 번째 문자 제외)가 나올
때마다 나누고
['The', 'Long', 'And', 'Winding', 'Road']
.
편집 :에서 그것은 또한 즉, 하나의 발생을 분할해야 'ABC'
내가 얻을 싶습니다
['A', 'B', 'C']
.
주어진 문자 집합이 발생하기 전에 문자열을 분할하는 비단뱀적인 방법 은 무엇입니까 ?
예를 들어, 'TheLongAndWindingRoad'
대문자 (아마도 첫 번째 문자 제외)가 나올
때마다 나누고
['The', 'Long', 'And', 'Winding', 'Road']
.
편집 :에서 그것은 또한 즉, 하나의 발생을 분할해야 'ABC'
내가 얻을 싶습니다
['A', 'B', 'C']
.
답변:
불행히도 파이썬에서는 너비가 0 인 일치 로 분할 할 수 없습니다 . 그러나 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']
'[a-zA-Z][^A-Z]*'
하면 정규식으로 사용 하십시오.
print(re.findall('^[a-z]+|[A-Z][^A-Z]*', 'theLongAndWindingRoad'))
다음은 대체 정규식 솔루션입니다. 문제는 "분할하기 전에 각 대문자 앞에 공백을 삽입하는 방법"으로 다시 표현할 수 있습니다.
>>> s = "TheLongAndWindingRoad ABC A123B45"
>>> re.sub( r"([A-Z])", r" \1", s).split()
['The', 'Long', 'And', 'Winding', 'Road', 'A', 'B', 'C', 'A123', 'B45']
이것은 대부분의 다른 솔루션이 그렇지 않은 모든 비 공백 문자를 보존하는 이점이 있습니다.
>>> 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']
rexeg를 변경 하기 "It'sATest"
위해 분할 ["It's", 'A', 'Test']
하려면"[A-Z][a-z']*"
drops
은 대문자로 시작하지 않는 모든 일반 (일반 알파) 단어 도 마찬가지 입니다. 나는 그것이 OP의 의도라고 의심합니다.
@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
import re
filter(None, re.split("([A-Z][^A-Z]*)", "TheLongAndWindingRoad"))
또는
[s for s in re.split("([A-Z][^A-Z]*)", "TheLongAndWindingRoad") if s]
[s for s in re.compile(r"([A-Z][^A-Z]*)").split( "TheLongAndWindingRoad") if s]
제공['The', 'Long', 'And', 'Winding', 'Road']
filter
조건이있는 목록 이해와 동일합니다. 그것에 반대하는 것이 있습니까?
filter(lambdaconditionfunc, ...)
파이썬 3) B를 filter()
반복자를 반환합니다. 따라서 그들은 완전히 동등하지 않을 것입니다. c) 저도 filter()
느리다고 생각합니다
src = 'TheLongAndWindingRoad'
glue = ' '
result = ''.join(glue + x if x.isupper() else x for x in src).strip(glue).split(glue)
더 나은 대답 은 문자열을 대문자로 끝나지 않는 단어로 나누는 것입니다. 이것은 문자열이 대문자로 시작하지 않는 경우를 처리합니다.
re.findall('.[^A-Z]*', 'aboutTheLongAndWindingRoad')
예:
>>> import re
>>> re.findall('.[^A-Z]*', 'aboutTheLongAndWindingRoadABC')
['about', 'The', 'Long', 'And', 'Winding', 'Road', 'A', 'B', 'C']
대체 솔루션 (명시 적 정규식을 싫어하는 경우) :
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
정규식이없고 원하는 경우 연속 대문자를 유지할 수있는 기능
def split_on_uppercase(s, keep_contiguous=False):
"""
Args:
s (str): string
keep_contiguous (bool): flag to indicate we want to
keep contiguous uppercase chars together
Returns:
"""
string_length = len(s)
is_lower_around = (lambda: s[i-1].islower() or
string_length > (i + 1) and s[i + 1].islower())
start = 0
parts = []
for i in range(1, string_length):
if s[i].isupper() and (not keep_contiguous or is_lower_around()):
parts.append(s[start: i])
start = i
parts.append(s[start:])
return parts
>>> split_on_uppercase('theLongWindingRoad')
['the', 'Long', 'Winding', 'Road']
>>> split_on_uppercase('TheLongWindingRoad')
['The', 'Long', 'Winding', 'Road']
>>> split_on_uppercase('TheLongWINDINGRoadT', True)
['The', 'Long', 'WINDING', 'Road', 'T']
>>> split_on_uppercase('ABC')
['A', 'B', 'C']
>>> split_on_uppercase('ABCD', True)
['ABCD']
>>> split_on_uppercase('')
['']
>>> split_on_uppercase('hello world')
['hello world']
이것은 more_itertools.split_before
도구 로 가능합니다 .
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'
I 'd like to get['A', 'B', 'C']
.
iterable = "ABC"
[ "".join(i) for i in mit.split_before(iterable, pred=lambda s: s.isupper())]
# ['A', 'B', 'C']
more_itertools
수동 구현을 제거하는 모든 원래 itertools 레시피 구현을 포함하여 60 개 이상의 유용한 도구가 포함 된 타사 패키지입니다 .
사용하는 또 다른 방법 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']
게시물을 읽을 때 떠오른 것을 공유합니다. 다른 게시물과 다릅니다.
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
Pythonic 방법은 다음과 같습니다.
"".join([(" "+i if i.isupper() else i) for i in 'TheLongAndWindingRoad']).strip().split()
['The', 'Long', 'And', 'Winding', 'Road']
re / re2를 피하면서 유니 코드에 잘 작동합니다.
"".join([(" "+i if i.isupper() else i) for i in 'СуперМаркетыПродажаКлиент']).strip().split()
['Супер', 'Маркеты', 'Продажа', 'Клиент']
주어진 모든 대문자 'L'을 빈 공간과 그 문자 "L"로 바꿉니다. 목록 이해를 사용하여이를 수행하거나 다음과 같이이를 수행하는 함수를 정의 할 수 있습니다.
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']
그러나 우리가 대문자로 문장을 분할하는 대부분의 경우, 일반적으로 대문자의 연속 스트림 인 약어를 유지하려는 경우가 일반적입니다. 아래 코드가 도움이 될 것입니다.
def splitAtUpperCase(s):
for i in range(len(s)-1)[::-1]:
if s[i].isupper() and s[i+1].islower():
s = s[:i]+' '+s[i:]
if s[i].isupper() and s[i-1].islower():
s = s[:i]+' '+s[i:]
return s.split()
splitAtUpperCase('TheLongANDWindingRoad')
>>> ['The', 'Long', 'AND', 'Winding', 'Road']
감사.