【问题标题】:Python : Splitting a string by numbers, letters and -_Python:用数字、字母和-_分割字符串
【发布时间】:2021-01-22 21:32:08
【问题描述】:

假设我有一个这样的字符串

string = 'rename_file_1122--23-_12'

有没有办法这样拆分

parts = ['rename','_','file','_','1122','--','23','-_','12']

我尝试了正则表达式,但它不起作用

import re

name_parts = re.findall('\d+|\D+|\w+|\W+', string)

结果是:

['rename_file_', '1122', '--', '23', '-_', '12']

##########第二部分

如果我有这样的字符串:

string2 = 'Hello_-Marco5__-'

我需要使用什么条件才能获得:['Hello','_-','Marco','5','__-']。我的目标是拆分字符串 y 组字母、数字和 '-_'。

感谢您的回答

【问题讨论】:

    标签: python regex string split


    【解决方案1】:

    你可以使用

    re.findall(r'[^\W_]+|[\W_]+', string)
    

    请参阅regex demo

    正则表达式详细信息

    • [^\W_]+ - 一个或多个非单词字符和_ 字符(即一个或多个字母或数字)
    • | - 或
    • [\W_]+ - 一个或多个非单词和/或 _ 字符。

    Python demo

    import re
    string = 'rename_file_1122--23-_12'
    name_parts = re.findall(r'[^\W_]+|[\W_]+', string)
    print(name_parts)
    # => ['rename', '_', 'file', '_', '1122', '--', '23', '-_', '12']
    

    【讨论】:

    • 当我查看这个正则表达式时,我做了几次双重拍摄,因为我想'wut?不匹配-“某物”还是匹配“某物”?这将匹配一切'。这正是它需要做的——找到“非某物”或“某物”,并继续匹配,直到找到相反的东西。不错!
    • @PranavHosangadi 这是一种标记化技术,当在一个模式中使用两个独立的相反替代方案时。它们最终匹配所有文本,没错,只是将其分为两种类型的标记。根据令牌类型,可能还有更多替代方案。
    【解决方案2】:

    您也可以使用groupby 中的itertools

    from itertools import groupby
    
    string = 'rename_file_1122--23-_12'
    
    result = [''.join(value) for key, value in groupby(string, key=str.isalnum)]
    
    print(result)
    

    输出:

    ['rename', '_', 'file', '_', '1122', '--', '23', '-_', '12']
    

    编辑:

    我想出了一个可能更简单的解决方案,使用正则表达式:

    string = 'rename_file_1122--23-_12'
    result = re.split('([_-]*)', string)
    print(result)
    

    同样的输出。

    re.split 将根据匹配正则表达式拆分字符串。我使用的表达式包含分组模式,而 split 在结果中包含匹配项:

    ([_-]*)
    

    表示匹配(并记住结果)一个或多个_- 中的任何一个的序列。 * 表示一个或多个,[] 表示方括号内的任何内容。

    没有组,只使用[_-]*,我们会得到以下内容,没有匹配项:

    string = 'rename_file_1122--23-_12'
    result = re.split('[_-]*', string)
    print(result)
    

    输出:

    ['rename', 'file', '1122', '23', '12']
    

    【讨论】:

      【解决方案3】:

      我找到了第二部分的解决方案,如下:

      name_parts=re.findall(r'[^\d_]+|[^\D]+|[^\W_]+|[\W_]+', string)
      

      【讨论】:

      • 用第二部分编辑问题不是很好。使我们的答案看起来不完整或不恰当。
      猜你喜欢
      • 2018-12-20
      • 2016-05-15
      • 2018-09-08
      • 1970-01-01
      • 1970-01-01
      • 2014-08-08
      • 2020-06-30
      • 2022-06-23
      • 1970-01-01
      相关资源
      最近更新 更多