我有一个包含日期和开始/停止时间的字符串。我已设法将日期从字符串中分离出来,但我不确定如何拉出开始/停止时间。
我的字符串看起来像Jun/22/177:57am5:13pm9:16
,其中Jun/22/17
是日期,7:57am
是开始时间,5:13pm
是停止时间,9:16
是持续时间以小时和分钟为单位。
我设法将日期值拉出到单独的变量中(以后再使用)
x = "Jun/22/177:57am5:13pm9:16"
fulldate_str = x[x.find(" ")+1:x.find("/17")+3]
fulldate = datetime.strptime(fulldate_str, "%b/%d/%y")
date_day = fulldate.day
date_month = fulldate.month
date_year = fulldate.year
但是我可以得到开始时间和结束时间吗?我可以使用
拉出其余的字符串inout = x[x.find("/17")+3:]
返回
7:57am5:13pm9:16
但我不确定如何在am
之后再次停留在pm
,然后再持续一段时间。开始时间并不总是am
,停止时间并不总是pm
,因此我认为我需要检查列表['am', 'pm']
,但
这样做有效,但前提是am
是第一个而pm
是第二个:
time_in = x[x.find("/17")+3:x.find("am",x.find("/17")+3)+2]
time_out = x[x.find("am",x.find("/17")+3)+2:x.find("pm")+2]
duration = x[x.find("pm")+2:]
当然我不需要 持续时间,因为它可以在以后轻松计算。
答案 0 :(得分:2)
这里的方法应该适用于am/pm
的任何顺序,并且还应该处理3或4位数的时间(例如,下午5:00和凌晨12:00):
x = "Jun/2/175:00pm12:00am9:16"
fulldate_str = x[x.find(" ")+1:x.find("/17")+3]
fulltime_spt = x[len(fulldate_str):].split("m")
for t in range(0,2):
fulltime_spt[t] += "m"
<强>输出:强>
['5:00pm', '12:00am', '9:16']
答案 1 :(得分:1)
pm
和am
最后都有一个m
,所以如果你知道时间字符串的格式总是如此,那么你可以拆分它然后再添加它相同。
[e if len(e) < 5 else e+'m' for e in '7:57am5:13pm9:16'.split('m')]
>>['7:57am', '5:13pm', '9:16']
如果您真的想使用RegEx查找时间,您还可以使用以下RegEx:
re.findall('[\d:]+(?:am|pm|$)', '7:57am5:13pm9:16')
>>['7:57am', '5:13pm', '9:16']
说明:该函数将查找与RegEx匹配的所有字符串。
[\d:]+
:数字或冒号一次或多次
(?:am|pm|$)
:指定am
,pm
或字符串结尾的非捕获组。
因此,RegEx将找到所有数字或冒号组,后跟am
或pm
或字符串的结尾。
答案 2 :(得分:1)
我使用re模块执行此操作,让我知道这是否是您需要的
import re
date = re.findall("[a-zA-Z]+/\d+/\d\d", x)[0] # Search for a group of upper or lower case letters, followed by / followed by 2 numbers followed by / followed by 2 numbers and return the first of these patterns found
start, stop = re.findall("\d+:\d+[ap]m", x[len(date):]) # search the string from the end of the date for a number (any amount of digits) followed by : followed by another number (of any amount of digits) and the string am or pm, and assign the first to start and second to stop
以下是一些例子。首先,我将它包装在练习函数中。让我们称之为f
import re
f(x):
date = re.findall("[a-zA-Z]+/\d+/\d\d", x)[0]
start, stop = re.findall("\d+:\d+[a|p]m", x[len(date):])
print(date, start, stop)
>>> f("Jun/22/177:57am5:13pm9:16")
Jun/22/17 7:57am 5:13pm
>>> f("May/13/1712:00am1:03pm")
May/13/17 12:00am 1:03pm
>>> f("Dec/1/1712:00am1:03pm")
Dec/1/17 12:00am 1:03pm
*我对获取日期的方式做了一些小改动,请注意。这样它可以处理1位数的月份。
答案 3 :(得分:1)
我的方法是使用正则表达式提取日期,开始和停止时间,从组件构建完整的开始日期时间和停止日期时间,然后使用它们将它们解析为datetime
个对象strptime
。一旦将它们存储为对象,就可以简单地减去它们以提供持续时间
这就是它的样子。我已经在时间之前用空格构建了start
和stop
字符串,以使它们更具可读性;解析器不需要它们
import re
from datetime import datetime
dts = "Jun/22/177:57am5:13pm9:16"
match = re.match(r'([a-z]{3}/\d\d/\d\d)(\d\d?:\d\d[ap]m)(\d\d?:\d\d[ap]m)', dts, flags=re.I)
if match :
start = '{} {}'.format(match.group(1), match.group(2))
stop = '{} {}'.format(match.group(1), match.group(3))
start = datetime.strptime(start, '%b/%d/%y %I:%M%p')
stop = datetime.strptime(stop, '%b/%d/%y %I:%M%p')
print(start)
print(stop)
2017-06-22 07:57:00
2017-06-22 17:13:00
[a-z]
匹配a
至z
的任何字母,[a-z]{3}
匹配其中三封m
\d
匹配十进制数字?
使前一项可选,因此\d\d?
匹配一位或两位数字[ap]
匹配a
或p
match.group(n)
和match.groups()
match
将为None
答案 4 :(得分:1)
一种方便的方法是使用正则表达式。如果您之前没有听说过,可以在documentation中阅读。基本上,它们允许您搜索字符串中的模式而不是特定字符。这是一个适用于您提到的字符串的示例。
# Import standard regular expression module
import re
# Find all substrings that match a specific pattern
x = "Jun/22/177:57am5:13pm9:16" # Our string
pattern = '[1-2]?[0-9]:[0-5][0-9][ap]m' # Explained below
re.findall(pattern, x) # Find all occurrences of pattern
结果:
['7:57am', '5:13pm']
例如,此模式可以找到持续时间
pattern2 = '[0-9]+:[0-9][0-9]$'
re.findall(pattern2, x)
结果:
['9:16']
让我们快速看看我们对正则表达式新手的第一个模式:
pattern = '[1-2]?[0-9]:[0-5][0-9][ap]m'
[]
表示“这些字符中的任何一个匹配”,?
表示“最后一个字符可能存在或不存在”。所以这看起来是1或2(但是如果因为?
没有1或2,我们没关系),接着是0到9之间的任何数字,接着是“:”,然后是数字从0到5,后跟0到9之间的数字,后跟“a”或“p”([ap]
),后跟“m”。
第二种模式有一个+
,它只是“一个或多个”,一个是$
,这意味着“这是字符串的结尾”。这应该可以帮助你开始。
另一种方法是,如果您不想使用正则表达式,.isdigit
命令可能会派上用场:
>>> '1'.isdigit()
True
>>> 'a'.isdigit()
False
答案 5 :(得分:-2)
以下将做
am
基本上你首先取消完整的日期(已经拆分),然后根据pm
和{{1}}进行字符串替换。