如何用冒号分割字符串,但如果不是,怎么办?

时间:2018-11-16 23:32:43

标签: python regex

给出一些长字符串:

s = "something blah blah: but it isn't 4:00 or 16:00 yet, how should we do this: that's it"

我希望能够得到一个返回字符串:

s = "something blah blah:\n but it isn't 4:00 or 16:00 yet, how should we do this:\n that's it"

这是我的代码更新(不起作用,因为它会分割字符串或根本不分割字符串):

def tokenize_time(s):
    #check if time is in string
    if re.search(ur"([:])", s):
        if not re.search(ur"([0-9]|[2][0-3]):([0-5][0-9])", s):
            s = re.sub(':', ':\n', s)
    return s 

2 个答案:

答案 0 :(得分:1)

您可以使用此:

countif

仅在冒号之前和之后使用非数字(>>> re.sub('(?=\D):(?<=\D)',':\n',s) "something blah blah:\n but it isn't 4:00 or 16:00 yet, how should we do this:\n that's it" )字符(使用\D?= lookaround assertions

时,才会匹配冒号)

答案 1 :(得分:1)

为什么不起作用:
您要它在整个字符串s中搜索一种模式ur"([:])"

如果找到匹配项,则希望它再次搜索整个字符串s,但是这次要搜索模式ur"([0-9]|[2][0-3]):([0-5][0-9])"

如果找到第一个模式,但未找到第二个模式,则进行替换re.sub(':', ':\n', s),将':'中的所有s替换为':\n'

您可能想要做的是:
1)在模式中结合(?<!...)后面的负数和(?!...)前面的负数,以定义描述“用冒号而不是时间的情况”的模式。

2)在字符串中搜索冒号,然后搜索匹配项周围的区域,以查看匹配项是否属于时间范围;如果不是,请更换该物品。

当然(1)效率更高,但是实施(2)可以帮助您了解解决方案为何不起作用。

这可能会有所帮助:
https://docs.python.org/3/library/re.html#re.search

解决方案#1: 您要替换的完全匹配模式应为:
(?<!(\b[0-1]?[0-9]|[2][0-3])):(?!([0-5][0-9])((?i)(am)|(pm))?\b)
所以你的一线便是:
s = re.sub(r'(?<!(\b[0-1]?[0-9]|[2][0-3])):(?!([0-5][0-9])((?i)(am)|(pm))?\b)', ':\n', s)
(正则表达式不是 so 在美学上令人愉悦吗?)

尝试将其插入此处进行测试:https://www.debuggex.com/
(请记住在下拉菜单中切换到Python。)

编辑:
我忘记了Python的后面必须固定宽度。一个草率的修复方法是使用以下模式:
(?<!([0-1\b][0-9]|[2][0-3])):(?!([0-5][0-9])((?i)(am)|(pm))?\b)
需要说明的是,它识别“像11:45之类的垃圾”包含时间,但正确地识别“像1:45之类的垃圾”不包含时间。

编辑#2:
进一步的检查表明Javascript根本不支持后退,因此即使您将其切换为Python模式,许多在线正则表达式测试人员也可能无法执行此操作。