【问题标题】:How can I split a string at the first occurrence of a letter in Python?如何在 Python 中第一次出现字母时拆分字符串?
【发布时间】:2016-06-07 04:50:10
【问题描述】:

A 有一系列格式如下的字符串。演示示例如下所示:

71 1 * abwhf

8 askg

*14 snbsb

00ab

我正在尝试编写一个 Python 3 程序,该程序将使用 for 循环循环遍历每个字符串,并在第一次出现字母时将其拆分为包含两个元素的列表。

上述字符串的输出将变成包含以下元素的列表:

71 1 *abwhf

8askg

*14snbsb

00ab

在前三个示例的第一个字符串之后有一个空格,但仅在编辑器中显示

这种方式如何拆分字符串?

这里有两个相关的帖子:

第一个问题的第一个答案允许我在第一次出现单个字符而不是多个字符(如字母表中的所有字母)时拆分字符串。

第二个允许我在第一个字母处拆分,但不仅仅是一次。使用它会产生一个包含许多元素的数组。

【问题讨论】:

    标签: python arrays regex string split


    【解决方案1】:

    使用re.search:

    import re
    
    strs = ["71 1 * abwhf", "8 askg", "*14 snbsb", "00ab"]
    
    
    def split_on_letter(s):
        match = re.compile("[^\W\d]").search(s)
        return [s[:match.start()], s[match.start():]]
    
    
    for s in strs:
        print split_on_letter(s)
    

    正则表达式[^\W\d] 匹配所有字母字符。

    \W 匹配所有非字母数字字符,\d 匹配所有数字字符。集合开头的^ 反转选择以匹配所有非字母数字(非字母数字或数字),对应于所有字母。

    match 搜索字符串以查找匹配表达式第一次出现的索引。您可以根据匹配的位置对原始字符串进行切片以获得两个列表。

    【讨论】:

    • 这很好用。对于 Python 3,需要在 print 函数周围添加方括号。
    【解决方案2】:

    我能想到的唯一方法就是自己写函数:

    import string
    
    def split_letters(old_string):
        index = -1
        for i, char in enumerate(old_string):
            if char in string.letters:
                index = i
                break
        else:
            raise ValueError("No letters found") # or return old_string
        return [old_string[:index], old_string[index:]]
    

    【讨论】:

    • 感谢您的回答。这非常整洁。运行它时,我收到一个异常:AttributeError: module 'string' has no attribute 'letters'
    • 对不起;我通常用 Python2 编写代码。在 Python3 中,它被重命名为 ascii_letters。如果您想要任何一种都可以使用的东西,请使用string.lowercase + string.uppercase
    【解决方案3】:

    使用 re.split()

    import re
    
    strings = [
        "71 1 * abwhf",
        "8 askg",
        "*14 snbsb",
        "00ab",
    ]
    
    for string in strings:
        a, b, c = re.split(r"([a-z])", string, 1, flags=re.I)
        print(repr(a), repr(b + c))
    

    生产:

    '71 1 * ' 'abwhf'
    '8 ' 'askg'
    '*14 ' 'snbsb'
    '00' 'ab'
    

    这里的诀窍是我们拆分任何字母,但只要求一个拆分。通过将模式放在括号中,我们保存了通常会丢失的拆分字符。然后我们将拆分字符添加回第二个字符串的前面。

    【讨论】:

      【解决方案4】:
      sample1 = '71 1 * abwhf'
      sample2 = '8 askg'
      sample3 = '*14 snbsb'
      sample4 = '00ab'
      sample5 = '1234'
      
      def split_at_first_letter(txt):
          for value in txt:
              if value.isalpha():
                  result = txt.split(value, 1)
                  return [result[0], '{}{}'.format(value, result[1], )]
      
          return [txt]
      
      print(split_at_first_letter(sample1))
      print(split_at_first_letter(sample2))
      print(split_at_first_letter(sample3))
      print(split_at_first_letter(sample4))
      print(split_at_first_letter(sample5))
      

      结果

      ['71 1 * ', 'abwhf']
      ['8 ', 'askg']
      ['*14 ', 'snbsb']
      ['00', 'ab']
      ['1234']
      

      【讨论】:

      • 感谢您的回答。 return 语句中的代码是如何工作的?
      • 上一行中的拆分删除了第二个列表项的第一个字符,为了替换该字符,从拆分的第一个元素(索引 0)和之前的字符创建一个新列表split 加上 split(index 1) 的第二个元素一起格式化。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-10
      相关资源
      最近更新 更多