【问题标题】:Regex : split by occurrences groups正则表达式:按出现组拆分
【发布时间】:2019-03-28 19:46:54
【问题描述】:

我正在尝试找到一种解决方案,按组中出现的次数拆分字符串。

字符串的格式如下:"AAA/BBB/CCC/DDD/BBB/CCC/DDD/BBB/DDD"

我希望字符串像这样拆分:

1)AAA/BBB/CCC/DDD

2)BBB/CCC/DDD

3)BBB/DDD

'/' 始终是分隔符,单词始终是 AAA、BBB、CCC 和 DDD。

我尝试使用带有 {x} 的正则表达式 (AAA|BBB|CCC|DDD){x} 来指定出现次数,但似乎 {} 仅适用于字符,而不适用于单词。

【问题讨论】:

    标签: regex python-3.x split find-occurrences


    【解决方案1】:

    您可以将re.findall 与以下正向前瞻模式一起使用,以确保仅当斜线后面跟随序列中允许的字符时才包含斜杠,并使用? 作为重复器来匹配每个单词可选(但贪婪):

    import re
    s = 'AAA/BBB/CCC/DDD/BBB/CCC/DDD/BBB/DDD'
    re.findall('(?=[ABCD])(?:AAA(?:/(?=[BCD]))?)?(?:BBB(?:/(?=[CD]))?)?(?:CCC(?:/(?=D))?)?(?:DDD)?', s)
    

    这会返回:

    ['AAA/BBB/CCC/DDD', 'BBB/CCC/DDD', 'BBB/DDD']
    

    【讨论】:

      【解决方案2】:

      您可以将re.split 与包含斜线的交替模式一起使用,斜线被正向后向和前向模式包围,以确保斜线前面的字符在序列中比斜线后面的字符晚:

      import re
      s = 'AAA/BBB/CCC/DDD/BBB/CCC/DDD/BBB/DDD'
      re.split('(?:(?<=[BCD])/(?=A)|(?<=[CD])/(?=B)|(?<=D)/(?=C))', s)
      

      这会返回:

      ['AAA/BBB/CCC/DDD', 'BBB/CCC/DDD', 'BBB/DDD']
      

      【讨论】:

      • 做得很好。 [.split] 版本看起来比 [.findall] 更紧凑。两者之间是否存在性能差异或任何其他优点/缺点?
      • 谢谢。尽管re.split 解决方案看起来更加紧凑和可读,但它使用后向模式的事实使其比仅使用前瞻模式的re.findall 解决方案慢得多。 Lookbehind 很慢,因为它在实现中需要更多步骤。请看演示时间:repl.it/repls/CorruptThankfulDatalog
      • blhsing:确实。 re.findall 版本快了将近 15%。再次感谢。
      猜你喜欢
      • 2012-04-20
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 1970-01-01
      • 2021-06-04
      • 1970-01-01
      相关资源
      最近更新 更多