예외가있는 문자열 케이스


87

문자열 타이틀 케이스 파이썬에서 표준적인 방법이지만 같은 떠나는 제품 (예 : 단어는 대문자로 시작하는 모든 나머지 맡았다 문자는 소문자가) 거기에 and, inof소문자?

답변:


151

이것에는 몇 가지 문제가 있습니다. 분할 및 결합을 사용하는 경우 일부 공백 문자가 무시됩니다. 기본 제공 대문자 및 제목 메서드는 공백을 무시하지 않습니다.

>>> 'There     is a way'.title()
'There     Is A Way'

문장이 기사로 시작하는 경우 제목의 첫 단어가 소문자로 표시되는 것을 원하지 않습니다.

다음 사항을 염두에 두십시오.

import re 
def title_except(s, exceptions):
    word_list = re.split(' ', s)       # re.split behaves as expected
    final = [word_list[0].capitalize()]
    for word in word_list[1:]:
        final.append(word if word in exceptions else word.capitalize())
    return " ".join(final)

articles = ['a', 'an', 'of', 'the', 'is']
print title_except('there is a    way', articles)
# There is a    Way
print title_except('a whim   of an elephant', articles)
# A Whim   of an Elephant

re필요한가요? 있다 "".split동일한 작업을 수행 기능.
wizzwizz4

1
@ wizzwizz4 : str.split연속 된 공백을 고려하지 않습니다. re.split공백을 유지합니다. 따라서이 함수는 공간을 차지하지 않습니다.
dheerosaur

@dheerosaur 나는 "".split()그들을 고려하지 않았지만 생각했다 "".split(" ").
wizzwizz4

스 니펫이 title_except('a whim of aN elephant', articles)케이스에 대해 올바르게 작동하지 않습니다 . word.lower() in exceptions필터링 조건을 사용 하여 수정할 수 있습니다.
다리우스 Walczak

@dheerosaur 기사뿐만 아니라 숫자 뒤에 오는 단어를 대문자로 표기하는 방법을 찾고 있습니다. 이를 증명하는 답변에 추가 할 수 있습니까? 예를 들어 2001 a Space Odyssey를 반환해야합니다 2001 A Space Odyssey. 여기서는 a숫자 다음에 따라 대문자로 표시됩니다. 미리 감사드립니다.
ProGrammer

53

titlecase.py 모듈을 사용하십시오 ! 영어로만 작동합니다.

>>> from titlecase import titlecase
>>> titlecase('i am a foobar bazbar')
'I Am a Foobar Bazbar'

GitHub : https://github.com/ppannuto/python-titlecase


1
변환중인 문자열에 숫자가 포함되어 있으면 제목 상자 모듈이 작동하지 않습니다.
Troy

1
@Troy 번호 문제가 해결되었거나 엣지 케이스를 치지 않은 것 같습니다. 예 : titlecase ( 'one 4 two')-> 'One 4 Two'. 이제 titlecase ( '1one')-> '1one',하지만 '1one'.title ()->'1One '. 이 나중 케이스는 엣지 케이스이고 '1One'이 올바른 제목인지 확실하지 않습니다. 나는 또한 문법 책을 잡을만큼 충분히 걱정하지 않습니다.
brent.payne 2014-09-22

"321 A BROADWAY STREET"의 경우 "321 a Broadway Street"가 표시되면 작동하지 않습니다. 위의 dheerosaur가 제안한 솔루션을 사용하면 "321 A Broadway Street"가 생성됩니다.
MoreScratch 2010 년

또한 제목에 약어를 그대로 둡니다. '혁신적인 TIaSR의 개발'이 '혁신적인 TIaSR의 개발'이됩니다.
Matthias Arras

22

다음과 같은 방법이 있습니다.

>>> mytext = u'i am a foobar bazbar'
>>> print mytext.capitalize()
I am a foobar bazbar
>>> print mytext.title()
I Am A Foobar Bazbar

소문자 기사 옵션이 없습니다. 낮추고 싶은 기사 목록을 사용하여 직접 코딩해야합니다.


titlecase.py 소문자 기사.
TRS-80

14

Stuart Colville은 문자열을 제목 케이스로 변환하기 위해 John Gruber작성한 Perl 스크립트 의 Python 포트 를 만들었지 만 New York Times Manual of style의 규칙에 따라 작은 단어를 대문자로 사용하지 않고 몇 가지 특별한 경우를 처리하지 않습니다.

이 스크립트의 영리함 :

  • if, in, of, on 등과 같은 작은 단어를 대문자로 표시 하지만 입력에서 잘못 대문자로 표시되면 대문자를 해제합니다.

  • 스크립트는 첫 번째 문자가 아닌 대문자로 된 단어가 이미 올바르게 대문자로 표시된 것으로 가정합니다. 이것은 그들이“iTunes”나 더 나쁜 것은“Itunes”로 바꾸는 대신“iTunes”와 같은 단어를 그대로 두는 것을 의미합니다.

  • 점이있는 단어는 건너 뜁니다. "example.com"및 "del.icio.us"는 소문자로 유지됩니다.

  • 그들은 "AT & T"및 "Q & A"와 같은 이상한 경우를 처리하기 위해 특별히 하드 코딩 된 해킹을 가지고 있으며 둘 다 일반적으로 소문자 여야하는 작은 단어 (at 및 a)를 포함합니다.

  • 제목의 첫 번째와 마지막 단어는 항상 대문자로 표시되므로 "무서워 할 내용 없음"과 같은 입력은 "무서워 할 내용 없음"으로 바뀝니다.

  • 콜론 뒤의 작은 단어는 대문자로 표시됩니다.

여기에서 다운로드 할 수 있습니다 .


4
capitalize (word)

그래야합니다. 나는 그것을 다르게 얻는다.

>>> mytext = u'i am a foobar bazbar'
>>> mytext.capitalize()
u'I am a foobar bazbar'
>>>

위의 답장에서 말했듯이 사용자 지정 대문자를 만들어야합니다.

mytext = u'i am a foobar bazbar '

def xcaptilize(word):
    skipList = ['a', 'an', 'the', 'am']
    if word not in skipList:
        return word.capitalize()
    return word

k = mytext.split(" ") 
l = map(xcaptilize, k)
print " ".join(l)   

이 출력

I am a Foobar Bazbar

그것은 내가 원하는 것이 아닙니다. "나는 Foobar Bazbar입니다"를 얻고 싶습니다
yassin

@Yassin Ezbakhe : 내 대답을 편집했습니다. 이것은 당신을 위해 작동합니다. 기사 목록은 모든 사전에서 쉽게 가져올 수 있습니다
pyfunc

2

Python 2.7의 제목 메서드에는 결함이 있습니다.

value.title()

'목수 반환 S 값이 목수 때 길잡이' 길잡이

가장 좋은 해결책은 아마도 Stuart Colville의 타이틀 케이스를 사용하는 @BioGeek의 솔루션 일 것입니다. @Etienne이 제안한 것과 동일한 솔루션입니다.


1
 not_these = ['a','the', 'of']
thestring = 'the secret of a disappointed programmer'
print ' '.join(word
               if word in not_these
               else word.title()
               for word in thestring.capitalize().split(' '))
"""Output:
The Secret of a Disappointed Programmer
"""

제목이 대문자로 시작하고 기사와 일치하지 않습니다.


1

목록 이해력과 삼항 연산자를 사용하는 한 줄

reslt = " ".join([word.title() if word not in "the a on in of an" else word for word in "Wow, a python one liner for titles".split(" ")])
print(reslt)

고장:

for word in "Wow, a python one liner for titles".split(" ") 문자열을 목록으로 분할하고 for 루프를 시작합니다 (목록 이해에서).

word.title() if word not in "the a on in of an" else wordtitle()기사가 아닌 경우 기본 방법 을 사용 하여 대소 문자를 문자열로 지정

" ".join (공백)의 구분자로 목록 요소를 결합합니다.


0

고려되지 않는 한 가지 중요한 경우는 약어입니다 (python-titlecase 솔루션은 명시 적으로 예외로 제공하는 경우 약어를 처리 할 수 ​​있습니다). 대신 단순히 다운 케이싱을 피하는 것이 좋습니다. 이 접근 방식을 사용하면 이미 대문자 인 약어는 대문자로 유지됩니다. 다음 코드는 원래 dheerosaur에서 제공 한 코드를 수정 한 것입니다.

# This is an attempt to provide an alternative to ''.title() that works with 
# acronyms.
# There are several tricky cases to worry about in typical order of importance:
# 0. Upper case first letter of each word that is not an 'minor' word.
# 1. Always upper case first word.
# 2. Do not down case acronyms
# 3. Quotes
# 4. Hyphenated words: drive-in
# 5. Titles within titles: 2001 A Space Odyssey
# 6. Maintain leading spacing
# 7. Maintain given spacing: This is a test.  This is only a test.

# The following code addresses 0-3 & 7.  It was felt that addressing the others 
# would add considerable complexity.


def titlecase(
    s,
    exceptions = (
        'and', 'or', 'nor', 'but', 'a', 'an', 'and', 'the', 'as', 'at', 'by',
        'for', 'in', 'of', 'on', 'per', 'to'
    )
):
    words = s.strip().split(' ')
        # split on single space to maintain word spacing
        # remove leading and trailing spaces -- needed for first word casing

    def upper(s):
        if s:
            if s[0] in '‘“"‛‟' + "'":
                return s[0] + upper(s[1:])
            return s[0].upper() + s[1:]
        return ''

    # always capitalize the first word
    first = upper(words[0])

    return ' '.join([first] + [
        word if word.lower() in exceptions else upper(word)
        for word in words[1:]
    ])


cases = '''
    CDC warns about "aggressive" rats as coronavirus shuts down restaurants
    L.A. County opens churches, stores, pools, drive-in theaters
    UConn senior accused of killing two men was looking for young woman
    Giant asteroid that killed the dinosaurs slammed into Earth at ‘deadliest possible angle,’ study reveals
    Maintain given spacing: This is a test.  This is only a test.
'''.strip().splitlines()

for case in cases:
    print(titlecase(case))

실행되면 다음이 생성됩니다.

CDC Warns About "Aggressive" Rats as Coronavirus Shuts Down Restaurants L.A. County Opens Churches, Stores, Pools, Drive-in Theaters
UConn Senior Accused of Killing Two Men Was Looking for Young Woman
Giant Asteroid That Killed the Dinosaurs Slammed Into Earth at ‘Deadliest Possible Angle,’ Study Reveals
Maintain Given Spacing: This Is a Test.  This Is Only a Test.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.