【问题标题】:split and group a string based on pattern in python根据python中的模式拆分和分组字符串
【发布时间】:2015-03-28 03:28:16
【问题描述】:

问题: 我有以下示例字符串:

ex1 = "00:03:34 hello!! this is example number 1 00:04:00"
ex2 = "00:07:08 Hi I am example number 2"

我希望它像下面这样分组(输出):

ex1 out : ("00:03:34", "hello!! this is example number 1", "00:04:00")
ex2 out : ("00:07:08", "Hi I am example number 2", None)

尝试:

我试过重新拆分:

time_pat = r"(\d{2}:\d{2}:\d{2})"
re.split(time_pat, ex1)
re.split(time_pat, ex2)

它给了我以下输出:

ex1 out : ['', '00:03:34', ' hello!! this is example number 1 ', '00:04:00', '']
ex2 out : ['', '00:07:08', ' Hi I am example number 2']

我将使用过滤器去除空白,然后输出将如下所示

ex1 out : ['00:03:34', ' hello!! this is example number 1 ', '00:04:00']
ex2 out : ['00:07:08', ' Hi I am example number 2']

这里的问题是 ex2 输出的长度为 2 而不是 3,第三个元素为 None。我知道如果长度为 2,我可以追加 None 但我不想这样做,我相信正则表达式可以做到。

我尝试了以下正则表达式:

re1 : r"(\d{2}:\d{2}:\d{2})(.*)(\d{2}:\d{2}:\d{2})"

很明显,它会解析 ex1 而不是 ex2

re2 : r"(\d{2}:\d{2}:\d{2})(.*)(\d{2}:\d{2}:\d{2})?"

这将解析两者,但第三个字符串始终为 None,因为正则表达式中的 ".*" 消耗了结束时间模式。

我尝试过前瞻断言,但我尝试错误,因此没有结果。谁能帮我在这里获取正则表达式?

【问题讨论】:

  • 如果输入是Hi I am example number 2,你的预期输出是什么?

标签: python regex python-2.7


【解决方案1】:

您可以按照您的建议使用前瞻,或者您可以只使用非贪婪捕获,一个可选组并指定您要匹配直到行尾 ($):

import re

ex1 = "00:03:34 hello!! this is example number 1 00:04:00"
ex2 = "00:07:08 Hi I am example number 2"

for ex in [ex1, ex2]:
    mat = re.match(r'(\d{2}:\d{2}:\d{2})\s(.*?)\s*(\d{2}:\d{2}:\d{2})?$', ex)
    if mat: print mat.groups()

输出:

('00:03:34', '你好!!这是示例编号 1', '00:04:00') ('00:07:08', '嗨,我是 2 号示例',无)

注意:这与您所拥有的非常接近——我只是对中间组使用了非贪婪捕获((.*?) 中的?)并在末尾添加了一个$ 来告诉它匹配整条线。如果没有非贪婪捕获,最后的可选时间戳将被中间组吃掉,并且没有指定要匹配到行尾,解析器甚至不会尝试匹配非贪婪的中间组和可选的时间戳,因为它不必这样做。

【讨论】:

  • 我建议您更改您的正则表达式,例如r'^(\d{2}:\d{2}:\d{2})?\s*(.*?)\s*(\d{2}:\d{2}:\d{2})?$',因为它也处理Hi I am example number 2 输入。
  • @AvinashRaj 你确定吗?我认为我没有在问题中看到这一点——没有前导时间戳的输入。
  • 感谢您的回答。我尝试过非贪婪捕获但没有使用 $.很好,你解释了。
【解决方案2】:

使用这种模式来捕获而不是拆分

^(\d{2}:\d{2}:\d{2})(.*?)((?:\d{2}:\d{2}:\d{2})|)$

Demo

【讨论】:

    猜你喜欢
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2020-09-25
    相关资源
    最近更新 更多