【问题标题】:Python title() with apostrophes带撇号的 Python 标题()
【发布时间】:2012-01-02 06:03:54
【问题描述】:

有没有办法使用.title() 从带有撇号的标题中获得正确的输出?例如:

"john's school".title() --> "John'S School"

我怎样才能在这里得到正确的标题,"John's School"

【问题讨论】:

    标签: python string uppercase


    【解决方案1】:

    恕我直言,最佳答案是@Frédéric's one。但是,如果您已经将字符串分隔为单词,并且知道string.capwords 是如何实现的,那么您可以避免不必要的加入步骤:

    def capwords(s, sep=None):
        return (sep or ' ').join(
            x.capitalize() for x in s.split(sep)
        )
    

    因此,您可以这样做:

    # here my_words == ['word1', 'word2', ...]
    s = ' '.join(word.capitalize() for word in my_words)
    

    【讨论】:

      【解决方案2】:

      虽然其他答案很有帮助,而且更简洁,但您可能会遇到一些问题。例如,如果您的字符串中有新的行或制表符。此外,在某些情况下,带连字符的单词(无论是常规连字符还是不间断连字符)以及以撇号开头的单词都可能是一个问题。但是,使用正则表达式(使用正则表达式替换参数的函数)可以解决这些问题:

      import re
      
      def title_capitalize(match):
          text=match.group()
          i=0
          new_text=""
          capitalized=False
          while i<len(text):
              if text[i] not in {"’", "'"} and capitalized==False:
                  new_text+=text[i].upper()
                  capitalized=True
              else:
                  new_text+=text[i].lower()
              i+=1
          return new_text
      
      def title(the_string):
          return re.sub(r"[\w'’‑-]+", title_capitalize, the_string)
      
      s="here's an apostrophe es. this string has multiple         spaces\nnew\n\nlines\nhyphenated words: and non-breaking   spaces, and a non‑breaking hyphen, as well as 'ords that begin with ’strophies; it\teven\thas\t\ttabs."
      print(title(s))
      

      无论如何,如果需要,您可以对其进行编辑以弥补任何进一步的问题,例如反引号和你有什么。

      如果您认为标题大小写应保持如介词、连词和冠词小写,除非它们位于标题的开头或结尾,您可以尝试使用此代码(但有一些模棱两可您必须根据上下文弄清楚的单词,例如when):

      import re
      
      lowers={'this', 'upon', 'altogether', 'whereunto', 'across', 'between', 'and', 'if', 'as', 'over', 'above', 'afore', 'inside', 'like', 'besides', 'on', 'atop', 'about', 'toward', 'by', 'these', 'for', 'into', 'beforehand', 'unlike', 'until', 'in', 'aft', 'onto', 'to', 'vs', 'amid', 'towards', 'afterwards', 'notwithstanding', 'unto', 'while', 'next', 'including', 'thru', 'a', 'down', 'after', 'with', 'afterward', 'or', 'those', 'but', 'whereas', 'versus', 'without', 'off', 'among', 'because', 'some', 'against', 'before', 'around', 'of', 'under', 'that', 'except', 'at', 'beneath', 'out', 'amongst', 'the', 'from', 'per', 'mid', 'behind', 'along', 'outside', 'beyond', 'up', 'past', 'through', 'beside', 'below', 'during'}
      
      def title_capitalize(match, use_lowers=True):
          text=match.group()
          lower=text.lower()
          if lower in lowers and use_lowers==True:
              return lower
          else:
              i=0
              new_text=""
              capitalized=False
              while i<len(text):
                  if text[i] not in {"’", "'"} and capitalized==False:
                      new_text+=text[i].upper()
                      capitalized=True
                  else:
                      new_text+=text[i].lower()
                  i+=1
              return new_text
      
      def title(the_string):
          first=re.sub(r"[\w'’‑-]+", title_capitalize, the_string)
          return re.sub(r"(^[\w'’‑-]+)|([\w'’‑-]+$)", lambda match : title_capitalize(match, use_lowers=False), first)
      

      【讨论】:

        【解决方案3】:

        这在一般情况下是困难的,因为一些单撇号后面跟着一个大写字符是合法的,例如以“O”开头的爱尔兰名字。 string.capwords() 在许多情况下都可以使用,但会忽略引号中的任何内容。 string.capwords("john's principal says,'no'") 不会返回您可能期望的结果。

        >>> capwords("John's School")
        "John's School"
        >>> capwords("john's principal says,'no'")
        "John's Principal Says,'no'"
        >>> capwords("John O'brien's School")
        "John O'brien's School"
        

        一个更烦人的问题是标题本身不会产生正确的结果。例如,在美国使用英语中,冠词和介词在标题或标题中通常不大写。 (芝加哥风格手册)。

        >>> capwords("John clears school of spiders")
        'John Clears School Of Spiders'
        >>> "John clears school of spiders".title()
        'John Clears School Of Spiders'
        

        您可以轻松安装titlecase module,它将对您更有用,并且做您喜欢的事情,而不会出现 capwords 的问题。当然,仍然存在许多边缘案例,但您会走得更远,而不必过多担心个人编写的版本。

        >>> titlecase("John clears school of spiders")
        'John Clears School of Spiders'
        

        【讨论】:

          【解决方案4】:

          如果您的标题在一行中不包含多个空白字符(会被折叠),您可以改用string.capwords()

          >>> import string
          >>> string.capwords("john's school")
          "John's School"
          

          编辑: 正如 Chris Morgan 在下面正确所说,您可以通过在 sep 参数中指定 " " 来缓解空格折叠问题:

          >>> string.capwords("john's    school", " ")
          "John's    School"
          

          【讨论】:

          • 这完全等同于' '.join(x.capitalize() for x in s.split())
          • 如果你关心不折叠多个空格,你可以指定sep参数:string.capwords("john's school", ' ')
          • @Chris,很好,我会相应地编辑我的答案。谢谢:)
          【解决方案5】:

          我认为title() 可能会很棘手

          让我们尝试一些不同的东西:

          def titlize(s):
              b = []
              for temp in s.split(' '): b.append(temp.capitalize())
              return ' '.join(b)
          
          titlize("john's school")
          
          // You get : John's School
          

          希望对您有所帮助.. !!

          【讨论】:

          • 这里不需要任何额外的库!
          • 恭喜,你刚刚重新实现了string.capwords()(顺便说一句,它在python的标准库中:)
          • @FrédéricHamidi 这不公平。 Yugal 代码不会带走空格,这是 string.capwords 的问题
          • @joaquin,你说得对,一开始我没有看到split() 的论点。因此,Yugal 的实现比 capwords() 更好,对于其他暗示表示歉意。
          • 没有更好。它的效率要低得多(逐项附加到列表而不是使用生成器表达式)。并且string.capwords 接受sep 参数,如果设置为' ' 将执行此操作。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          • 1970-01-01
          • 1970-01-01
          • 2020-05-06
          • 1970-01-01
          相关资源
          最近更新 更多