【问题标题】:Cleanest way to obtain the numeric prefix of a string获取字符串数字前缀的最简洁方法
【发布时间】:2016-06-22 08:48:48
【问题描述】:

在 Python 中获取字符串数字前缀的最简洁方法是什么?

“干净”是指简单、简短、易读。我完全不在乎性能,而且我认为它在 Python 中几乎无法衡量。

例如:

给定字符串'123abc456def',获取字符串'123'的最干净的方法是什么?

以下代码获取'123456'

input = '123abc456def'
output = ''.join(c for c in input if c in '0123456789')

所以我基本上是在寻找某种方法来用while 替换if

【问题讨论】:

  • 可以选择正则表达式吗?
  • @MaxU:我希望有一个简单的“字符串操作”可以让我摆脱正则表达式的负担,但如果你认为没有其他选择,那么可以。
  • 所有前缀都是 3 个字符还是不同?
  • @AIG:不,它会有所不同(否则,我会使用input[0:3])。
  • @ForceBru:谢谢。下面有一个答案比您建议的问题中接受的答案更适合我的问题(即,下面的答案是“更干净”),所以我会在这里接受。

标签: python string python-2.7 python-3.x


【解决方案1】:

这是我的方式:

output = input[:next((i for i,v in enumerate(input) if not v.isdigit()),None)]

【讨论】:

    【解决方案2】:

    您可以使用 itertools.takewhile 迭代您的字符串(可迭代参数),直到遇到第一个返回 False 的项目(通过传递给预测函数):

    >>> from itertools import takewhile
    >>> input = '123abc456def'
    >>> ''.join(takewhile(str.isdigit, input))
    '123'
    

    【讨论】:

    • 请投票重新提出这个问题。有两个建议的副本。一个是不同的问题(!!!),另一个是自己关闭的,此外,这里的答案比对那个(关闭的)问题的接受答案更符合我的问题,因为它满足了我对最干净的要求可能的解决方案。谢谢。
    • 非常感谢。你能看看下面@dementedhedgehog 提出的解决方案吗?它似乎很“干净”,但我不愿意不接受你的回答。
    • @barakmanos 我在那里留下了评论。它更短,但在内存使用方面不是最佳的。它还使用了一个索引和两个len 函数。
    • 如果我们要这样,这个问题特别指出性能并不重要(并不总是如此)。
    • 我会支持任何看起来像 Haskell 的解决方案。在我看来,这绝对是“最干净”的解决方案。
    【解决方案3】:

    一种方法,但效率不高,因为它可以在没有break 的情况下处理整个字符串:

    input_string = '123abc456def'
    [input_string[:c] for c in range(len(input_string)) if input_string[:c].isdigit()][-1]
    

    如果它是一个数字,这会附加每个子串的大小,然后附加它。所以最后一个元素就是你要找的那个。因为它是最长的仍然是数字的起始字符串。

    【讨论】:

      【解决方案4】:

      这是从字符串中提取数字列表的最简单方法:

      >>> import re
      >>> input = '123abc456def'
      >>> re.findall('\d+', s)
      ['123','456']
      

      如果您需要一个 int 列表,那么您可以使用以下代码:

         >>> map(int, re.findall('\d+', input ))
         [123,456]
      

      现在您可以访问上面列表中的第一个元素 [0]

      【讨论】:

      • 这是一个大胆的声明。虽然我认为这是一个很好的解决方案。
      • 也许match() 更合适,因为 OP 只需要起始数字。
      【解决方案5】:

      你可以使用正则表达式

      import re
      initialNumber = re.match(r'(?P<number>\d+)', yourInput).group('number')
      

      【讨论】:

        【解决方案6】:
        input[:len(input) - len(input.lstrip("0123456789"))]
        

        【讨论】:

        • 这不是内存使用方面的优化方法(特别是当您处理较大的字符串时)。因为您正在从主字符串创建一个剥离的字符串并将其加载到内存中。
        • 是的。它不是特别有效,但是该帖子特别不关心性能,而且它很简单,实际上性能通常并不重要。你必须使用大字符串来关心。例如,在编译正则表达式时也会有开销。如果您真的关心速度,请使用 c。
        • 还取决于字符串的哪个部分是前缀。如果是一百万位数字后跟“x”,那么您的方法也会很慢。可能较慢,因为您有副本以及一堆函数调用开销?我很想看看我们两种方法与字符串长度和前缀长度的时间比较。
        【解决方案7】:

        更简单的版本(留下另一个答案,因为关于哪种方法更好有一些有趣的争论)

        input[:-len(input.lstrip("0123456789"))]
        

        【讨论】:

        • 这是pythonic ;),但正如我所说,takewhile() 在内存使用方面更加优化。
        • 确实如此。我将不得不再看一下 itertools.. 直到现在我还没有听说过 takewhile。
        【解决方案8】:

        另一个正则表达式版本删除了从第一个非数字开始的所有内容:

        import re
        output = re.sub('\D.*', '', input)
        

        【讨论】:

          【解决方案9】:
          input = '123abc456def'
          output = re.findall(r'^\d+', input)
          

          也会返回['123']

          【讨论】:

            猜你喜欢
            • 2016-07-15
            • 1970-01-01
            • 1970-01-01
            • 2010-09-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-05-25
            • 1970-01-01
            相关资源
            最近更新 更多