【问题标题】:Find the index of the first digit in a string查找字符串中第一个数字的索引
【发布时间】:2011-05-29 11:37:04
【问题描述】:

我有一个类似

的字符串
"xdtwkeltjwlkejt7wthwk89lk"

如何获取字符串中第一个数字的索引?

【问题讨论】:

    标签: python regex string


    【解决方案1】:
    instr = 'nkfnkjbvhbef0njhb h2konoon8ll'
    numidx = next((i for i, s in enumerate(instr) if s.isdigit()), None)
    print(numidx)
    

    输出:

    12
    

    numidx 将是instr 中第一次出现的数字的索引。如果instr 中没有数字,则numidx 将是None

    我在这里没有看到这个解决方案,并认为应该是。

    【讨论】:

    【解决方案2】:

    Python 3.8+ 中,您可以使用 re.search 查找第一个 \d(用于 digit)字符类,如下所示:

    import re
    
    my_string = "xdtwkeltjwlkejt7wthwk89lk"
    
    if first_digit := re.search(r"\d", my_string):
        print(first_digit.start())
    

    【讨论】:

      【解决方案3】:
      import re
      result = "  Total files:...................     90"
      match = re.match(r".*[^\d](\d+)$", result)
      if match:
          print(match.group(1))
      

      会输出

      90
      

      【讨论】:

      • 请考虑在您的答案中添加代码的简短说明。
      • 这会返回第一组数字,而不仅仅是第一个数字。
      • 这只有在最后一个字符是数字时才有效
      【解决方案4】:
      import re
      first_digit = re.search('\d', 'xdtwkeltjwlkejt7wthwk89lk')
      if first_digit:
          print(first_digit.start())
      

      【讨论】:

        【解决方案5】:

        使用re.search():

        >>> import re
        >>> s1 = "thishasadigit4here"
        >>> m = re.search(r"\d", s1)
        >>> if m:
        ...     print("Digit found at position", m.start())
        ... else:
        ...     print("No digit in that string")
        ... 
        Digit found at position 13
        

        【讨论】:

        • 如果有人对性能感兴趣,我会尝试一些不同的方法——正则表达式是最快的:gist.github.com/1683249
        • 你会用什么代替m.start() 来获取找到的数字(在本例中为 4)?
        • @zanahorias 你可以使用m.group(0)
        • 自 @umbrae 的基准测试以来已经有很长时间了,目前在 Python 3.7.8 上,isdigit() 方法对我来说始终快了大约 5-6%。
        【解决方案6】:

        要获取所有索引,请执行以下操作:

        idxs = [i for i in range(0, len(string)) if string[i].isdigit()]
        

        然后获取第一个索引:

        if len(idxs):
            print(idxs[0])
        else:
            print('No digits exist')
        

        【讨论】:

        • IndexError 如果您的字符串没有数字,将被提升。
        • 单线更好!
        【解决方案7】:

        这是一种更好更灵活的方式,这里正则表达式是多余的。

        s = 'xdtwkeltjwlkejt7wthwk89lk'
        
        for i, c in enumerate(s):
            if c.isdigit():
                print(i)
                break
        

        输出:

        15
        

        要获取所有数字及其位置,一个简单的表达式就可以了

        >>> [(i, c) for i, c in enumerate('xdtwkeltjwlkejt7wthwk89lk') if c.isdigit()]
        [(15, '7'), (21, '8'), (22, '9')]
        

        或者您可以创建一个数字字典及其最后位置

        >>> {c: i for i, c in enumerate('xdtwkeltjwlkejt7wthwk89lk') if c.isdigit()}
        {'9': 22, '8': 21, '7': 15}
        

        【讨论】:

          【解决方案8】:
          def first_digit_index(iterable):
              try:
                  return next(i for i, d in enumerate(iterable) if d.isdigit())
              except StopIteration:
                  return -1
          

          这不使用正则表达式,一旦找到第一个数字就会停止迭代。

          【讨论】:

            【解决方案9】:

            以为我会把我的方法扔在一堆。我会做任何事情来避免正则表达式。

            sequence = 'xdtwkeltjwlkejt7wthwk89lk'
            i = [x.isdigit() for x in sequence].index(True)
            

            解释这里发生了什么:

            • [x.isdigit() for x in sequence] 会将字符串转换为布尔数组,表示每个字符是否为数字
            • [...].index(True) 返回找到 True 的第一个索引值。

            【讨论】:

            • 如果您的字符串没有数字,这将引发ValueError
            【解决方案10】:

            这是另一种无正则表达式的方式,更多的是功能风格。这个找到字符串中存在的每个数字第一次出现的位置,然后选择最低的。正则表达式可能会更有效,尤其是对于较长的字符串(这使得至少 10 次完整的字符串通过,最多 20 次)。

            haystack = "xdtwkeltjwlkejt7wthwk89lk"
            digits   = "012345689"
            found    = [haystack.index(dig) for dig in digits if dig in haystack]
            firstdig = min(found) if found else None
            

            【讨论】:

              【解决方案11】:

              你可以使用正则表达式

              import re
              y = "xdtwkeltjwlkejt7wthwk89lk"
              
              s = re.search("\d",y).start()
              

              【讨论】:

              • AttributeError 如果您的字符串没有任何数字,则会引发。
              【解决方案12】:

              正如其他解决方案所说,要找到字符串中第一个数字的索引,我们可以使用正则表达式:

              >>> s = 'xdtwkeltjwlkejt7wthwk89lk'
              >>> match = re.search(r'\d', s)
              >>> print match.start() if match else 'No digits found'
              15
              >>> s[15] # To show correctness
              '7'
              

              虽然很简单,但正则表达式匹配对于超长字符串来说将是多余的。一种更有效的方法是像这样遍历字符串:

              >>> for i, c in enumerate(s):
              ...     if c.isdigit():
              ...         print i
              ...         break
              ... 
              15
              

              如果我们想将问题扩展到查找第一个 整数(不是数字)以及它是什么:

              >>> s = 'xdtwkeltjwlkejt711wthwk89lk'
              >>> for i, c in enumerate(s):
              ...     if c.isdigit():
              ...         start = i
              ...         while i < len(s) and s[i].isdigit():
              ...             i += 1
              ...         print 'Integer %d found at position %d' % (int(s[start:i]), start)
              ...         break
              ... 
              Integer 711 found at position 15
              

              【讨论】:

              • 可以在匹配对象中找到位置。查看我的解决方案。
              【解决方案13】:

              对于解析器来说似乎是一份不错的工作:

              >>> from simpleparse.parser import Parser
              >>> s = 'xdtwkeltjwlkejt7wthwk89lk'
              >>> grammar = """
              ... integer := [0-9]+
              ... <alpha> := -integer+
              ... all     := (integer/alpha)+
              ... """
              >>> parser = Parser(grammar, 'all')
              >>> parser.parse(s)
              (1, [('integer', 15, 16, None), ('integer', 21, 23, None)], 25)
              >>> [ int(s[x[1]:x[2]]) for x in parser.parse(s)[1] ]
              [7, 89]
              

              【讨论】:

              • 这肯定是矫枉过正,但这里有一个很好的食谱!
              • @jsbueno:谢谢,确实有点矫枉过正(至少在你必须扩展模式匹配之前,有时我很难理解我两个月前写的正则表达式):-)
              • 这个答案比任何教程都教会了我更多关于如何使用 simpleparse 的知识。
              【解决方案14】:

              我确定有多种解决方案,但使用正则表达式可以做到这一点:

              >>> import re
              >>> match = re.search("\d", "xdtwkeltjwlkejt7wthwk89lk")
              >>> match.start(0)
              15
              

              【讨论】:

              • AttributeError 如果您的字符串没有任何数字,则会引发。
              猜你喜欢
              • 2017-02-23
              • 1970-01-01
              • 2020-08-02
              • 1970-01-01
              • 2012-05-02
              • 1970-01-01
              • 2018-01-19
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多