从列表中的值中查找字符串中的第一个文本实例

时间:2017-06-23 20:15:02

标签: python list

我有一个包含日期和开始/停止时间的字符串。我已设法将日期从字符串中分离出来,但我不确定如何拉出开始/停止时间。

我的字符串看起来像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'],但

  1. 我不知道怎么做,
  2. 我认为应该有更好的方法来做到这一点。
  3. 这样做有效,但前提是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:]
    

    当然我不需要 持续时间,因为它可以在以后轻松计算。

6 个答案:

答案 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)

pmam最后都有一个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|$):指定ampm或字符串结尾的非捕获组。

因此,RegEx将找到所有数字或冒号组,后跟ampm或字符串的结尾。

答案 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。一旦将它们存储为对象,就可以简单地减去它们以提供持续时间

这就是它的样子。我已经在时间之前用空格构建了startstop字符串,以使它们更具可读性;解析器不需要它们

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]匹配az的任何字母,[a-z]{3}匹配其中三封
  • 斜杠和冒号匹配,m
  • 也是如此
  • \d匹配十进制数字
  • ?使前一项可选,因此\d\d?匹配一位或两位数字
  • [ap]匹配ap
  • 括号&#34;捕获&#34;他们匹配的字符串,可通过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}}进行字符串替换。