【问题标题】:How would I get everything before a : in a string Python我如何在字符串 Python 中获得 a 之前的所有内容
【发布时间】:2015-02-07 20:17:04
【问题描述】:

我正在寻找一种方法来获取字符串中的所有字母 a : 但我不知道从哪里开始。我会使用正则表达式吗?如果有怎么办?

string = "Username: How are you today?"

有人可以给我举个例子吗?

【问题讨论】:

    标签: python regex string split


    【解决方案1】:

    只需使用split 函数。它返回一个列表,因此您可以保留第一个元素:

    >>> s1.split(':')
    ['Username', ' How are you today?']
    >>> s1.split(':')[0]
    'Username'
    

    【讨论】:

    • 要么 limit 拆分,或者在这种情况下 - 使用 s1.partition(':')[0]
    • 谢谢,这非常有用且内容丰富。另外,这是一个很大的帮助,谢谢!
    • 不要使用 split,因为它会处理所有的 ':' 并创建一个完整的数组,不适合较长的字符串。请参阅@Hackaholic 使用索引的方法。只是那个人还推荐了一个显然没有那么有效的正则表达式。还必须有一个 python 选项来执行基于索引的 .substringBefore() 的标准操作。为了方便起见,还应该有 .substringBeforeLast() 等变体(代码不应重复)。注意到关于分区的要点 - 是的,':' 之后的处理较少,但仍然返回 : ('1', ':', '2:3') 而不是 '1'。
    【解决方案2】:

    使用index:

    >>> string = "Username: How are you today?"
    >>> string[:string.index(":")]
    'Username'
    

    索引将为您提供: 在字符串中的位置,然后您可以对其进行切片。

    如果你想使用正则表达式:

    >>> import re
    >>> re.match("(.*?):",string).group()
    'Username'                       
    

    match 从字符串的开头匹配。

    你也可以使用itertools.takewhile

    >>> import itertools
    >>> "".join(itertools.takewhile(lambda x: x!=":", string))
    'Username'
    

    【讨论】:

    • 这个方法(string[:string.index(":")])可能比split更干净
    • 为了速度不要使用正则表达式 - 使用这里提到的第一个索引选项。正则表达式显然没有那么有效。还必须有一个 python 选项来执行基于索引的 .substringBefore() 的标准操作。为了方便起见,还应该有 .substringBeforeLast() 等变体(代码不应重复)。建议更新此答案以解释为什么该索引效果更好,然后为什么应该使用它而不是其他方法,包括现在在 fredtantini 的回应中投票更高的方法。
    • 如果不存在,索引将失败。
    • 这里在正则表达式中: re.match("(.*?):",string).group() 为什么我们需要一个'?'不应该这样做 re.match("(.*):",string).group()
    • 不应该是re.match("(.*?):",string).group(1)(如果没有冒号可能需要检查一下)? re.match("(.*?):",string).group() 似乎仍然包含冒号。
    【解决方案3】:

    你不需要 regex 来做这个

    >>> s = "Username: How are you today?"
    

    您可以使用split 方法在':' 字符上拆分字符串

    >>> s.split(':')
    ['Username', ' How are you today?']
    

    并切出元素[0] 以获取字符串的第一部分

    >>> s.split(':')[0]
    'Username'
    

    【讨论】:

      【解决方案4】:

      我已经在 Python 3.7.0 (IPython) 下对这些不同的技术进行了基准测试。

      TLDR

      • 最快(当拆分符号c 已知时):预编译的正则表达式。
      • 最快(否则):s.partition(c)[0]
      • 安全(即,当c 可能不在s 中时):分区、拆分。
      • 不安全:索引、正则表达式。

      代码

      import string, random, re
      
      SYMBOLS = string.ascii_uppercase + string.digits
      SIZE = 100
      
      def create_test_set(string_length):
          for _ in range(SIZE):
              random_string = ''.join(random.choices(SYMBOLS, k=string_length))
              yield (random.choice(random_string), random_string)
      
      for string_length in (2**4, 2**8, 2**16, 2**32):
          print("\nString length:", string_length)
          print("  regex (compiled):", end=" ")
          test_set_for_regex = ((re.compile("(.*?)" + c).match, s) for (c, s) in test_set)
          %timeit [re_match(s).group() for (re_match, s) in test_set_for_regex]
          test_set = list(create_test_set(16))
          print("  partition:       ", end=" ")
          %timeit [s.partition(c)[0] for (c, s) in test_set]
          print("  index:           ", end=" ")
          %timeit [s[:s.index(c)] for (c, s) in test_set]
          print("  split (limited): ", end=" ")
          %timeit [s.split(c, 1)[0] for (c, s) in test_set]
          print("  split:           ", end=" ")
          %timeit [s.split(c)[0] for (c, s) in test_set]
          print("  regex:           ", end=" ")
          %timeit [re.match("(.*?)" + c, s).group() for (c, s) in test_set]
      

      结果

      String length: 16
        regex (compiled): 156 ns ± 4.41 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
        partition:        19.3 µs ± 430 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
        index:            26.1 µs ± 341 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        split (limited):  26.8 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        split:            26.3 µs ± 835 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        regex:            128 µs ± 4.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
      
      String length: 256
        regex (compiled): 167 ns ± 2.7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
        partition:        20.9 µs ± 694 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        index:            28.6 µs ± 2.73 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        split (limited):  27.4 µs ± 979 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        split:            31.5 µs ± 4.86 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        regex:            148 µs ± 7.05 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
      
      String length: 65536
        regex (compiled): 173 ns ± 3.95 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
        partition:        20.9 µs ± 613 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
        index:            27.7 µs ± 515 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        split (limited):  27.2 µs ± 796 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        split:            26.5 µs ± 377 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        regex:            128 µs ± 1.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
      
      String length: 4294967296
        regex (compiled): 165 ns ± 1.2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
        partition:        19.9 µs ± 144 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
        index:            27.7 µs ± 571 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        split (limited):  26.1 µs ± 472 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        split:            28.1 µs ± 1.69 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
        regex:            137 µs ± 6.53 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
      

      【讨论】:

      • 你为什么认为 index 不安全?
      • c 不在s 中时,s.index(c) 会引发 ValueError。因此,当我确定要分区的字符串包含分隔符时,我认为它是安全的,否则不安全。
      • 对于索引,c在s中,所以不是不安全的,还是最快的。
      【解决方案5】:

      partition() 可能比 split() 更好,因为它在没有分隔符或更多分隔符的情况下具有更好的可预测结果。

      【讨论】:

      • partitionsplit 都可以透明地使用空字符串或不使用分隔符。值得注意的是,word[:word.index(':')] 在这两种情况下都会弹出。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      相关资源
      最近更新 更多