【问题标题】:How to split a string based on underscore but conditional如何根据下划线但有条件地拆分字符串
【发布时间】:2021-07-27 15:14:15
【问题描述】:

我有一个字符串,下面用下划线_ 完全连接,我想以这种方式拆分以获得我想要的输出。

下面是列表字符串:

>>> a
'cDOT_stv3027_esx_vdi01_07-24-2021_02.00.00.0443'

>>> type(a)
<type 'str'>

2 的简单rsplit() 操作将其转换为 3 个不同的列表值,如下所示,例如从末尾开始其 timedate 然后一个组合字符串,即 'cDOT_stv3027_esx_vdi01' 我想分成两部分,比如'cDOT' & 'stv3027_esx_vdi01'

>>> a.rsplit("_",2)
['cDOT_stv3027_esx_vdi01', '07-24-2021', '02.00.00.0443']

我在下面的第一个索引上尝试,但我不会保留其余的值。

>>> a.rsplit("_",2)[0].split("_",1)
['cDOT', 'stv3027_esx_vdi01']

我想要的输出应该如下所示:

['cDOT', 'stv3027_esx_vdi01', '07-24-2021', '02.00.00.0443']

【问题讨论】:

  • 在我看来,只要加入您的 2 个(子)列表,您就已经拥有了所需的一切:a.rsplit("_",2)[0].split("_",1) + a.rsplit("_",2)[1:]
  • @Demi-Lune,这成功了,感谢您的帮助。
  • 感谢大家的大力帮助。

标签: python python-3.x regex


【解决方案1】:

你可以使用

a = 'cDOT_stv3027_esx_vdi01_07-24-2021_02.00.00.0443'
prefix, *mid, date, time = a.split('_')
print(prefix, '_'.join(mid), date, time)

见在线Python demo

在这种情况下,前缀和日期之间可以有尽可能多的下划线分隔部分。

【讨论】:

  • 感谢 WiKtor 已经提供了不同的方法 +1,顺便说一下 *mid 特别是 * ,如果你很少解释的话。
  • @kulfi "Splat" 或 "unpacking" 操作符,见more here
【解决方案2】:

假设您总是希望连接的子字符串相同:

splits = a.split('_')
[splits[0]] + ['_'.join(splits[1:4])] + splits[4:]

>>> [splits[0]] + ['_'.join(splits[1:4])] + splits[4:]
['cDOT', 'stv3027_esx_vdi01', '07-24-2021', '02.00.00.0443']

【讨论】:

    【解决方案3】:

    在我看来,您并不是真的想拆分数据,而是想提取相关部分。为此,我建议使用正则表达式。

    import re
    
    m = re.match(r"^(.*)_(.*_.*_.*)_(.*)_(.*)$", a)
    
    # Your results:
    [m.group(1), m.group(2), m.group(3), m.group(4)]
    

    通过这种方式,您可以捕获所有内容,直到第 1 组中的第一个下划线,接下来的三个下划线将部分分隔到第 2 组,日期在第 3 组,最后部分到第 4 组。

    因此结果将如下所示:

    ['cDOT', 'stv3027_esx_vdi01', '07-24-2021', '02.00.00.0443']
    

    【讨论】:

      【解决方案4】:

      为什么不分两步做呢?

      string = 'cDOT_stv3027_esx_vdi01_07-24-2021_02.00.00.0443'
      
      splited_line = string.rsplit('_', 2)
      print(splited_line[0].split('_', 1) + splited_line[1:])
      

      输出:

      ['cDOT', 'stv3027_esx_vdi01', '07-24-2021', '02.00.00.0443']
      

      【讨论】:

        【解决方案5】:

        使用正则表达式:

        >>> re.findall('(.*?)_(.*?)_(\d+.*?)_(.*)', a)[0]
        ('cDOT', 'stv3027_esx_vdi01', '07-24-2021', '02.00.00.0443')
        

        理解模式:

        (.*?)_(.*?)_(\d+.*?)_(.*)
        
        (.*?)_ : It will match the substring before first underscore
        
        (.*?)_(\d+.*?)_ : It will match the substring until underscore followed by 
                          at least one digits, but will get you one substring before underscore, 
                          and one sebstring after underscore and before the next underscore 
                          encountered
        
        (.*) : It will get the remaining part of the string.
        
        

        【讨论】:

          【解决方案6】:

          在一行中使用split()rsplit()partition()

          a.split('_')[:1] + a.partition('_')[2].rsplit('_', 2)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-04-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多