문자열을 대문자로 분할
주어진 문자 집합이 발생하기 전에 문자열을 분할하는 파이토닉 방법은 무엇입니까?
예를 들면, 나는 갈라지기를 원합니다.'TheLongAndWindingRoad'
대문자(첫번째를 제외한 possibly)가 발생하면 다음을 얻을 수 있습니다.['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']
여기에 대안적인 regex 솔루션이 있습니다.이 문제는 "분할을 수행하기 전에 각 대문자 앞에 공백을 삽입하는 방법"으로 대체할 수 있습니다.
>>> s = "TheLongAndWindingRoad ABC A123B45"
>>> re.sub( r"([A-Z])", r" \1", s).split()
['The', 'Long', 'And', 'Winding', 'Road', 'A', 'B', 'C', 'A123', 'B45']
이를 통해 공백이 아닌 모든 문자를 보존할 수 있는 장점이 있지만, 대부분의 다른 솔루션에서는 그렇지 않습니다.
미리 보기와 뒤 보기를 사용합니다.
Python 3.7에서는 다음을 수행할 수 있습니다.
re.split('(?<=.)(?=[A-Z])', 'TheLongAndWindingRoad')
결과는 다음과 같습니다.
['The', 'Long', 'And', 'Winding', 'Road']
처음에 빈 줄을 피하려면 뒤를 봐야 합니다.
>>> 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']
reexeg를 로 바꿉니다."[A-Z][a-z']*"
@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
더 나은 답은 줄을 대문자로 끝나지 않는 단어로 나누는 것일 수도 있다고 생각합니다.이렇게 하면 문자열이 대문자로 시작하지 않는 경우를 처리할 수 있습니다.
re.findall('.[^A-Z]*', 'aboutTheLongAndWindingRoad')
예:
>>> import re
>>> re.findall('.[^A-Z]*', 'aboutTheLongAndWindingRoadABC')
['about', 'The', 'Long', 'And', 'Winding', 'Road', 'A', 'B', 'C']
import re
filter(None, re.split("([A-Z][^A-Z]*)", "TheLongAndWindingRoad"))
아니면
[s for s in re.split("([A-Z][^A-Z]*)", "TheLongAndWindingRoad") if s]
파이토닉 방식은 다음과 같습니다.
"".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()
['Супер', 'Маркеты', 'Продажа', 'Клиент']
src = 'TheLongAndWindingRoad'
glue = ' '
result = ''.join(glue + x if x.isupper() else x for x in src).strip(glue).split(glue)
정규성이 없는 또 다른 기능과 원하는 경우 연속 대문자를 유지할 수 있습니다.
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']
대체 솔루션(명시적 정규화를 싫어하는 경우):
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
주어진 문자에 있는 모든 대문자 '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']
감사해요.
정규식 또는 열거식을 사용하지 않는 대체 방법:
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(' ')
너무 많은 방법을 연결하지 않고, 읽기 어려울 수 있는 긴 목록 이해력을 사용하지 않고 더 명확하고 간단하다고 생각합니다.
이는 공구로 가능합니다.
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']
.
iterable = "ABC"
[ "".join(i) for i in mit.split_before(iterable, pred=lambda s: s.isupper())]
# ['A', 'B', 'C']
more_itertools
는 모든 오리지널 이터툴 레시피에 대한 구현을 포함한 60개 이상의 유용한 툴이 포함된 타사 패키지로, 이들의 수동 구현은 생략됩니다.
사용하는 다른 방법과
코드:
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
당신도 이런 식으로 하고 싶을 겁니다
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']
def solution(s):
st = ''
for c in s:
if c == c.upper():
st += ' '
st += c
return st
리스트를 사용하고 있습니다.
def split_by_upper(x):
i = 0
lis = list(x)
while True:
if i == len(lis)-1:
if lis[i].isupper():
lis.insert(i,",")
break
if lis[i].isupper() and i != 0:
lis.insert(i,",")
i+=1
i+=1
return "".join(lis).split(",")
출력:
data = "TheLongAndWindingRoad"
print(split_by_upper(data))`
>> ['The', 'Long', 'And', 'Winding', 'Road']
대문자 분할에 대한 나의 해결책 - 대문자를 유지합니다.
text = 'theLongAndWindingRoad ABC'
result = re.sub('(?<=.)(?=[A-Z][a-z])', r" ", text).split()
print(result)
#['the', 'Long', 'And', 'Winding', 'Road', 'ABC']
파티에 좀 늦었지만:
In [1]: camel = "CamelCaseConfig"
In [2]: parts = "".join([
f"|{c}" if c.isupper() else c
for c in camel
]).lstrip("|").split("|")
In [3]: screaming_snake = "_".join([
part.upper()
for part in parts
])
In [4]: screaming_snake
Out[4]: 'CAMEL_CASE_CONFIG'
내 대답의 일부는 여기서 오는 다른 사람들의 대답에 근거를 두고 있습니다.
def split_string_after_upper_case(word):
word_lst = [x for x in word]
index = 0
for char in word[1:]:
index += 1
if char.isupper():
word_lst.insert(index, ' ')
index += 1
return ''.join(word_lst).split(" ")
k = split_string_after_upper_case('TheLongAndWindingRoad')
print(k)
언급URL : https://stackoverflow.com/questions/2277352/split-a-string-at-uppercase-letters
'programing' 카테고리의 다른 글
WebKitFormBoundary는 무엇을 의미합니까? (0) | 2023.10.22 |
---|---|
그룹화되지 않은 Oracle 결과: (0) | 2023.10.22 |
JVM 프로세스는 메모리를 어떻게 할당합니까? (0) | 2023.10.22 |
jQuery .close()와 비슷하지만 후손을 횡단합니까? (0) | 2023.10.22 |
PL/MySQL이 존재합니까? (0) | 2023.10.22 |