Regex: Text the line after a match

Viewed 109

I'm working with a file that has times and values on the next line after the times. I can extract the times into a list but need to get the value of the line following also. This would be a list of time/value pairs.

file looks like this:

10:30 AM
F
10:40 AM

10:50 AM
F
11:00 AM
1
11:10 AM

11:20 AM
1
11:30 AM
1
11:40 AM
1
11:50 AM
1
12:00 PM

12:10 PM
1
12:20 PM
1
12:30 PM
1
12:40 PM
1
12:50 PM
1

The code i'm using to get the times is this:

get_source = driver.page_source  
soup = BeautifulSoup(get_source, 'html.parser')
time_pattern = re.compile(r'\s(\d{1,2}\:\d{2}\s?(?:AM|PM|am|pm))')
times = time_pattern.findall(soup.get_text())

Where

times = ['10:30 AM', '10:40 AM', '10:50 AM', '11:00 AM'........]

I want to also get the value of the next line (blank, F, or 1) creating a time/value pair.

timesvaluepair = [[10:30 AM, 'F'],[10:40 AM, ''],[10:50 AM, 'F'],[11:00 AM, '1'],.........]

How would you do this?

3 Answers

You only need to slightly modify your current regex to capture both the time and value, in separate capture groups:

inp = """10:30 AM
F
10:40 AM

10:50 AM
F
11:00 AM
1
11:10 AM

11:20 AM
1
11:30 AM
1
11:40 AM
1"""

matches = re.findall(r'\b(\d{1,2}\:\d{2}\s?(?:AM|PM|am|pm))\r?\n(\S*)', inp)
print(matches)

This prints:

[('10:30 AM', 'F'), ('10:40 AM', ''),  ('10:50 AM', 'F'), ('11:00 AM', '1'),
 ('11:10 AM', ''),  ('11:20 AM', '1'), ('11:30 AM', '1'), ('11:40 AM', '1')]

You could try something like this:

myfile = open('test.txt', 'r')
lines = myfile.readlines()

dataset = []
item = []
for line in lines:

    line = line.strip()

    if ':' in line:
        if len(item) > 0:
            dataset.append(item)
            item = []

    item.append(line)

dataset.append(item)

print(dataset)

Result

[['10:30 AM', 'F'], ['10:40 AM', ''], ['10:50 AM', 'F'], ['11:00 AM', '1'], ['11:10 AM', ''], ['11:20 AM', '1'], ['11:30 AM', '1'], ['11:40 AM', '1'], ['11:50 AM', '1'], ['12:00 PM', ''], ['12:10 PM', '1'], ['12:20 PM', '1'], ['12:30 PM', '1'], ['12:40 PM', '1'], ['12:50 PM', '1']]

Explanation

  • dataset is your final list of pairs
  • item is the pair of time and its following line
  • we read all lines from the file
  • we remove the \n from the line with strip()
  • if the line has a : in it, we check if the item has something in it
    • if it does, that means item already has a pair and the pair should be added to dataset
    • empty the item
  • add the line back to the item
  • keep on doing that till you reach the end; at the end add the item back to the dataset

You might also make it a bit more specific and match a timelike format followed by a newline, and optionally match F or 1 using a character class.

\b((?:1[0-2]|0?[1-9]):[0-5][0-9]\s?(?:AM|PM|am|pm))\r?\n([F1]?)

Explanation

  • \b A word boundary
  • ( Capture group 1
    • (?:1[0-2]|0?[1-9]) Match 0-9 with optional leading 0 or 10, 11 12
    • :[0-5][0-9]\s? Match from 00 - 59
    • (?:AM|PM|am|pm) Match one of the alternatives
  • ) Close group 1
  • \r?\n Match a newline
  • ([F1]?) Capture group 2, optionally match either F or 1

See a regex demo and a Python demo.

Related