我需要编写一个正则表达式来从字符串中查找视频中的时间标记。例如,我有这个:
00:00 - вступление Сергея Немчинского
01:26 - профессия это не на всю жизнь
04:45 - важность выбора языка программирования
07:48 - системы управления контролем версий
09:51 - поисковик
12:10 - больше практики
13:12 - и больше отдыха
14:38 - программирование это больше чем синтаксис
17:15 - невозможно выучить все
10:19:38 - разберитесь в себе и делайте то, что нравится :)
我需要提取[00:00, 01:26, 04:45, etc.]
我有这个(?:(?:([01]?d|2[0-3]):)?([0-5]?d):)?([0-5]?d)$
,但它不能正常工作。
s = '''00:00 - вступление Сергея Немчинского
01:26 - профессия это не на всю жизнь
04:45 - важность выбора языка программирования
07:48 - системы управления контролем версий
09:51 - поисковик
12:10 - больше практики
13:12 - и больше отдыха
14:38 - программирование это больше чем синтаксис
17:15 - невозможно выучить все
10:19:38 - разберитесь в себе и делайте то, что нравится :)'''
import re
re.findall(r'^d[d:]+', s, re.MULTILINE)
# ['00:00',
# '01:26',
# '04:45',
# '07:48',
# '09:51',
# '12:10',
# '13:12',
# '14:38',
# '17:15',
# '10:19:38']
此处的正则表达式描述
您的模式包含前两个部分的可选捕获组。这样,它也将匹配例如仅10
您可以省略末尾的锚$
,并在开头添加锚^
。
则仅使最后一组可选,因为示例数据10:19:38
中的最后一个值由3部分组成。
^(?:[01]?d|2[0-3]):[0-5]?d(?::[0-5]?d)?b
模式匹配:
^
字符串开始(?:[01]?d|2[0-3])
从00到19或从20到23匹配:[0-5]?d
从00到59匹配(?::[0-5]?d)?
可选匹配00到59b
防止部分匹配的字边界
Regex演示| Python演示
示例
import re
pattern = r"^(?:[01]?d|2[0-3]):[0-5]?d(?::[0-5]?d)?b"
s = ("00:00 - вступление Сергея Немчинскогоn"
"01:26 - профессия это не на всю жизньn"
"04:45 - важность выбора языка программированияn"
"07:48 - системы управления контролем версийn"
"09:51 - поисковикn"
"12:10 - больше практикиn"
"13:12 - и больше отдыхаn"
"14:38 - программирование это больше чем синтаксисn"
"17:15 - невозможно выучить всеn"
"10:19:38 - разберитесь в себе и делайте то, что нравится :)n")
print(re.findall(pattern, s, re.MULTILINE))
输出
['00:00', '01:26', '04:45', '07:48', '09:51', '12:10', '13:12', '14:38', '17:15', '10:19:38']
假设如下:
- 时间总是在一行的开头
- 时间的格式可以是
00:00
、00:00:00
或00:00:00.00
然后:
s = '''
00:00 - вступление Сергея Немчинского
01:26 - профессия это не на всю жизнь
04:45 - важность выбора языка программирования
07:48 - системы управления контролем версий
09:51 - поисковик
12:10 - больше практики
13:12 - и больше отдыха
14:38 - программирование это больше чем синтаксис
17:15 - невозможно выучить все
10:19:38 - разберитесь в себе и делайте то, что нравится :)
'''
# extract times as tuples of strings [('', '00', '00'), ('', '01, '26'), ...]
times = re.findall(r'^(?:(dd):)?(dd):(dd(?:.d*)?)', s, re.M)
# convert to integers and floats [(0, 0, 0.0), (0, 1, 26.0), ...]
times = [(int(h or 0), int(m), float(s or 0)) for h, m, s in times]
# convert to timedeltas [timedelta(0), timedelta(0, 86), ...]
times = [datetime.timedelta(hours=h, minutes=m, seconds=s) for h, m, s in times]
# results
for time in times:
print(time)
0:00:00
0:01:26
0:04:45
0:07:48
0:09:51
0:12:10
0:13:12
0:14:38
0:17:15
10:19:38
正则表达式包含以下部分:
^
必须从行的开头开始(?:(dd):)
可选小时部件,如00:
(dd):
需要像00:
一样的分钟部分(dd(?:.d*)?)
需要具有可选小数的第二部分,如00
或00.00
每个数字都与()
分组,因此findall
将为每个元素元组返回一个字符串数字。
之所以使用模式int(h or 0)
,是因为正则表达式可以返回不是有效int
的''
,但'' or 0
变为有效int
的0
。