给出一些长字符串:
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
答案 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模式,许多在线正则表达式测试人员也可能无法执行此操作。