Kot Enot
Kot Enot

Reputation: 19

I need correct regex for time markers in video

I need to write a regular expression to find time markers in the video from a string. For example, I have this:

00:00 - вступление Сергея Немчинского
01:26 - профессия это не на всю жизнь
04:45 - важность выбора языка программирования
07:48 - системы управления контролем версий
09:51 - поисковик
12:10 - больше практики
13:12 - и больше отдыха
14:38 - программирование это больше чем синтаксис
17:15 - невозможно выучить все
10:19:38 - разберитесь в себе и делайте то, что нравится :)

I need to extract [00:00, 01:26, 04:45, etc.] I have this (?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)$ But it doesen't works properly.

Upvotes: 1

Views: 107

Answers (3)

The fourth bird
The fourth bird

Reputation: 163577

Your pattern contains optional capture groups for the first 2 parts. That way it will also match for example just 10

You can omit the anhor $ at the end, and add an anchor ^ at the start.

Then only make the last group optional as the last value in the example data 10:19:38 consists of 3 parts.

^(?:[01]?\d|2[0-3]):[0-5]?\d(?::[0-5]?\d)?\b

The pattern matches:

  • ^ Start of string
  • (?:[01]?\d|2[0-3]) Match from 00 to 19 or 20 to 23
  • :[0-5]?\d Match from 00 to 59
  • (?::[0-5]?\d)? Optionally match from 00 to 59
  • \b A word boundary to prevent a partial match

Regex demo | Python demo

Example

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

Output

['00:00', '01:26', '04:45', '07:48', '09:51', '12:10', '13:12', '14:38', '17:15', '10:19:38']

Upvotes: 1

Pi Marillion
Pi Marillion

Reputation: 4674

Assuming the following:

  • Time is always at the very start of a line
  • Time can have format 00:00, 00:00:00, or 00:00:00.00

Then:

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'^(?:(\d\d):)?(\d\d):(\d\d(?:\.\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

The regex has these parts:

  • ^ must start at beginning of line
  • (?:(\d\d):) optional hour part like 00:
  • (\d\d): required minute part like 00:
  • (\d\d(?:\.\d*)?) required second part with optional decimal like 00 or 00.00

Each number is grouped with () so that findall will return one string-number-per-element tuples.

The pattern int(h or 0) is used because the regex can return '' which isn't a valid int, but '' or 0 becomes 0 which is a valid int.

Upvotes: 0

Epsi95
Epsi95

Reputation: 9047

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']

Description of the regex here

Upvotes: 2

Related Questions