【问题标题】:How to capitalize first letter in strings that may contain numbers如何将可能包含数字的字符串中的第一个字母大写
【发布时间】:2018-11-01 10:17:00
【问题描述】:

我想使用 Python 通读文件并将字符串中的第一个字母大写,但某些字符串可能首先包含数字。具体来说,该文件可能如下所示:

"hello world"
"11hello world"
"66645world hello"

我希望是这样的:

"Hello world"
"11Hello world"
"66645World hello"

我尝试了以下方法,但只有在字母位于第一个位置时才会大写。

with open('input.txt') as input, open("output.txt", "a") as output:
    for line in input:
        output.write(line[0:1].upper()+line[1:-1].lower()+"\n")

有什么建议吗? :-)

【问题讨论】:

    标签: python string capitalization


    【解决方案1】:

    使用正则表达式:

    for line in output:
        m = re.search('[a-zA-Z]', line);
        if m is not None:
            index = m.start()
            output.write(line[0:index] + line[index].upper() + line[index + 1:])
    

    【讨论】:

    • 仅使用 [a-z] 的问题是它可以匹配可能不是字符串中第一个字母的字母(如果第一个字母已经是大写)。
    • @AnkitJaiswal 是的,我不是很正式,但是有很多错误检查可以进入这个答案以使其更健壮。
    【解决方案2】:

    您可以使用正则表达式查找第一个字母的位置,然后在该索引上使用upper() 将该字符大写。像这样的东西应该可以工作:

    import re
    
    s =  "66645hello world"
    m = re.search(r'[a-zA-Z]', s)
    index = m.start()
    

    【讨论】:

      【解决方案3】:

      你可以编写一个带有for循环的函数:

      x = "hello world"
      y = "11hello world"
      z = "66645world hello"
      
      def capper(mystr):
          for idx, i in enumerate(mystr):
              if not i.isdigit():  # or if i.isalpha()
                  return ''.join(mystr[:idx] + mystr[idx:].capitalize())
          return mystr
      
      print(list(map(capper, (x, y, z))))
      
      ['Hello world', '11Hello world', '66645World hello']
      

      【讨论】:

      • 如果没有第一个字母出现在空格之后的情况,这将起作用。
      • @AnkitJaiswal,是的,这不需要任何拆分。因此,只要 OP 的用户案例可以接受 str.isdigit,它应该可以工作。
      • 把条件倒过来用string.isalpha()代替不是更好吗?
      • @AnkitJaiswal,不确定什么更有效。在大多数 情况下,虽然不是全部,但它们是等价的。你能举一个它不起作用的例子吗?
      【解决方案4】:

      这个怎么样?

      import re
      
      text = "1234hello"
      index = re.search("[a-zA-Z]", text).start()
      text_list = list(text)
      text_list[index] = text_list[index].upper()
      
      ''.join(text_list)
      

      结果是:1234Hello

      【讨论】:

        【解决方案5】:

        可能值得一试...

        >>> s = '11hello World'
        >>> for i, c in enumerate(s):
        ...     if not c.isdigit():
        ...         break
        ... 
        >>> s[:i] + s[i:].capitalize()
        '11Hello world'
        

        【讨论】:

          【解决方案6】:

          您可以找到第一个字母字符并将其大写,如下所示:

          with open("input.txt") as in_file, open("output.txt", "w") as out_file:
              for line in in_file:
                  pos = next((i for i, e in enumerate(line) if e.isalpha()), 0)
                  line = line[:pos] + line[pos].upper() + line[pos + 1:]
                  out_file.write(line)
          

          哪些输出:

          Hello world
          11Hello world
          66645World hello
          

          【讨论】:

          • 在我看来,这比正则表达式更可取。
          • @jpp 这不也允许非字母吗?这只是检查数字。
          • @AnkitJaiswal 好点。将其更改为忽略除字母以外的所有内容。
          【解决方案7】:

          像这样,例如:

          import re
          
          re_numstart = re.compile(r'^([0-9]*)(.*)')
          
          def capfirst(s):
              ma = re_numstart.match(s)
              return ma.group(1) + ma.group(2).capitalize()
          

          【讨论】:

            【解决方案8】:

            试试这个:

            with open('input.txt') as input, open("output.txt", "a") as output:
            for line in input:
                t_line = ""
                for c in line:
                    if c.isalpha():
                        t_line += c.capitalize()
                        t_line += line[line.index(c)+1:]
                        break
                    else:
                        t_line += c
                output.write(t_line)
            

            执行结果:

            Hello world
            11Hello world
            66645World hello
            

            【讨论】:

              【解决方案9】:

              您可以为此使用regular expression

              import re
              
              line = "66645world hello"
              
              regex = re.compile(r'\D')
              tofind = regex.search(line)
              pos = line.find(tofind.group(0))+1
              
              line = line[0:pos].upper()+line[pos:-pos].lower()+"\n"
              
              print(line)
              

              输出:66645World

              【讨论】:

                【解决方案10】:

                可能有一种单行 REGEX 方法,但使用 title() 也应该可以工作:

                def capitalise_first_letter(s):
                    spl = s.split()
                    return spl[0].title() + ' ' + ' '.join(spl[1:])
                
                s = ['123hello world',
                "hello world",
                "11hello world",
                "66645world hello"]
                
                
                for i in s:
                    print(capitalise_first_letter(i))
                

                制作:

                Hello world
                11Hello world
                66645World hello
                

                【讨论】:

                  【解决方案11】:

                  好的,已经有很多答案了,应该可以的。

                  我发现它们过于复杂或复杂...

                  这是一个更简单的解决方案:

                  for s in ("hello world", "11hello world", "66645world hello"):
                      first_letter = next(c for c in s if not c.isdigit())
                      print(s.replace(first_letter, first_letter.upper(), 1))
                  

                  【讨论】:

                    【解决方案12】:

                    title() 方法会将字符串的第一个字母字符大写,并忽略它之前的数字。它也适用于非 ASCII 字符,这与使用 [a-zA-Z] 的正则表达式方法相反。

                    来自文档:

                    str.title()

                    返回单词的标题版本的字符串 以大写字符开头,其余字符为 小写。 [...] 该算法使用简单的语言无关 将单词定义为一组连续的字母。定义 在许多情况下都有效,但这意味着收缩中的撇号 和所有格形成单词边界,这可能不是我们想要的 结果:

                    我们可以这样利用它:

                    def my_capitalize(s):
                        first, rest = s.split(maxsplit=1)
                        split_on_quote = first.split("'", maxsplit=1)
                        split_on_quote[0] = split_on_quote[0].title()
                        first = "'".join(split_on_quote)
                    
                        return first + ' ' + rest
                    

                    一些测试:

                    tests = ["hello world", "11hello world", "66645world hello", "123ça marche!", "234i'm good"]
                    for s in tests:
                        print(my_capitalize(s))
                    
                    # Hello world
                    # 11Hello world
                    # 66645World hello
                    # 123Ça marche!  # The non-ASCII ç was turned to uppercase
                    # 234I'm good    # Words containing a quote are treated properly
                    

                    【讨论】:

                      【解决方案13】:

                      re.subrepl 作为函数:

                      如果 repl 是一个函数,它会在每个不重叠的地方调用 模式的发生。该函数采用单个匹配对象 参数,并返回替换字符串。

                      def capitalize(m):
                          return m.group(1) + m.group(2).upper() + m.group(3)
                      
                      lines = ["hello world", "11hello world", "66645world hello"]
                      for line in lines:
                          print re.sub(r'(\d*)(\D)(.*)', capitalize, line)
                      

                      输出:

                      你好世界 11你好世界 66645世界你好

                      【讨论】:

                        【解决方案14】:

                        对字符串使用 isdigit() 和 title():

                        s = ['123hello world', "hello world", "11hello world", "66645world hello"]
                        print [each if each[0].isdigit() else each.title() for each in s ]
                        
                        
                        # ['123hello world', 'Hello World', '11hello world', '66645world hello']                                                                          
                        

                        【讨论】:

                          【解决方案15】:

                          如果你想转换以字符开头的字符串而不是数字后的字符大写,你可以试试这段代码:

                          def solve(s):
                              str1 =""
                              for i in s.split(' '):
                                  str1=str1+str(i.capitalize()+' ') #capitalizes the first character of the string
                              return str1
                          
                          >>solve('hello 5g')
                          >>Hello 5g
                          

                          【讨论】:

                          • 这不适用于“123adf asdf”。预期答案是“123Adf Asdf”。
                          • @SRIDHARAN 你没看到我在代码之前写了什么吗?我想完全实现你刚才提到的。我想将每个以字符开头的单词大写,但如果其他单词不以字符开头,则保持小写。
                          • 但上面提出的问题不需要那个。请参阅上面发布的示例。
                          猜你喜欢
                          • 2022-01-09
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2015-07-24
                          • 2013-06-11
                          相关资源
                          最近更新 更多