#🔒 ReGex help

26 messages · Page 1 of 1 (latest)

naive elm
#

Hi, I need some help with ReGex, I'm trying to separate timestamps from title tracks. Timestamps can be to the left or right of the title

1. Master Morality 00:00:03
...
39:17 9. Pechmarie
TIMESTAMP_PATTERN = r"((?:\d{2}:)+(?:\d{2}){1})"
with open(txt, "r", encoding="utf-8") as f:
        for song in f.readlines():
            song = "".join([c for c in song if c.isprintable()])
            song_data = re.split(TIMESTAMP_PATTERN, song.strip())
            print(song_data)
# output
['1. Master Morality ', '00:00:03', '']
...
['', '39:17', ' 9. Pechmarie']

I have a few issues with this:

  • I have empty strings on the split
  • I need to use song = "".join([c for c in song if c.isprintable()]) to remove newline and other control characters from matches (is there a better way of doing this?)
  • I need to get the name of the song and the timestamp separately. Right now using split, the name of the song can either be the first or the last element, which is not convenient
    -> Is there any way of getting two groups, one that matches the TIMESTAMP_PATTERN and another that matches all the rest?

Thanks!

violet ospreyBOT
#

@naive elm

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

eager mauve
#

you could do something like this, ^(?P<time>\d{2}:\d{2}(?::\d{2})?)\s*(?P<name>.+)$|^(?P<name2>.+?)\s*(?P<time2>\d{2}:\d{2}(?::\d{2})?)$

#

which is a lot to just drop

steady kettle
#

Y'all are overcomplicating it

#

question - is it always going to be one of the following?

timestamp
number.
title

or
number.
title
timestamp

naive elm
eager mauve
#

you can just filter the falsey elements

naive elm
steady kettle
#

ok

#

This is what i got
(.*?)((\d+\.)?[\sa-zA-Z]+)(.*)

eager mauve
#

[elem for elem in list if elem]

#

also the regex i sent has named capture groups (still haven't gotten a chance to type out the intuition!)

lime horizon
#

i bet there's some nasty songs with names like 00:05 🥴

naive elm
#
        for song in f.readlines():
            song = "".join([c for c in song if c.isprintable()])
            song_timestamp = re.findall(TIMESTAMP_PATTERN, song.strip())[0]
            song_title = song.replace(song_timestamp, "")

This works with the original regex

steady kettle
naive elm
steady kettle
eager mauve
#

you can have two regexes to make this a bit more readable ```py
timestamp = r"(?P<time>\d{2}:\d{2}(?::\d{2})?)"
name = r"(?P<name>.+?)"

timestamp_first = re.compile(fr"^{timestamp}\s*{name}$")
timestamp_last = re.compile(fr"^{name}\s*{timestamp}$")

#

and then you can access the capture groups by variable name, rather than number

lime horizon
#

!e Perhaps you could just remove the match:

import re
TIMESTAMP_PATTERN = r"((?:\d{2}:)+(?:\d{2}))"
for s in """1. Master Morality 00:00:03
39:17 9. Pechmarie""".splitlines():
    ts = re.search(TIMESTAMP_PATTERN, s)
    print(ts)
    if ts:
        rest = s.replace(ts.group(0), "")
        print(rest)
violet ospreyBOT
naive elm
#

Thanks a lot! I'll check out the different options and see what ends up working and being the most readable 🙂

#

!close

violet ospreyBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.