Python: Reading full sentence which includes next line but not always

Viewed 59

I have a text file like this,

#:  Two before narrow not relied how except moment myself.  
     
%:  So gate at no only none open. Betrayed at properly it of graceful on
    Dinner abroad am depart ye turned hearts as me wished.

#:  Ham followed now ecstatic use speaking exercise may repeated Himself he evident oh 
    greatly my on inhabit general concern.

%:  Therefore allowance too perfectly gentleman supposing man his now
    Families goodness all eat out bed steepest servants.

I only want to print the lines that starts with '#:' but I want the full sentence rather one line, here's what I have done,

f = open("text.txt", "r")

for line in f:
    if line.startswith("#:"):
        print(line)

output:

#:  Two before narrow not relied how except moment myself.  

#:  Ham followed now ecstatic use speaking exercise may repeated Himself he evident oh

Expected output:

#:  Two before narrow not relied how except moment myself.  
         
   
#:  Ham followed now ecstatic use speaking exercise may repeated Himself he evident oh 
    greatly my on inhabit general concern.
    
    

Notice that the second '#:' sentence only contains one line rather than the whole sentence, if I use next(f) it will also consider sentence starting with '%:'. Any ideas?

3 Answers

An other simple solution is to remember the status of your reading:

f = open("text.txt", "r")

in_line = False
for line in f:
    if line.startswith("#:"):
        print(line)
        in_line = True
    elif in_line:
        if line.startswith("%:"):
            in_line = False
        else:
            print(line)

This way allow to separate # and % parts and store data in parse-friendly dictionary:

PARTS = {'#': [], '%': []}

with open("text.txt", "r") as f:
  current_marker = None
  for line in f.readlines():
    # uncomment these lines if you want to skip empty rows
    # if line in ('\r\n', '\n'):
    #   continue
    for marker in PARTS.keys():
      if line.startswith(marker):
        current_marker = marker
    if current_marker in PARTS:
      PARTS[current_marker].append(line.rstrip('\r\n'))
    elif current_marker:
      PARTS[current_marker][-1:] = (''.join(PARTS[current_marker][-1:] + [line])).rstrip('\r\n')
    else:
      continue

for k in PARTS:
  print('-------')
  print(f' {k} is')
  print('-------')
  for line in PARTS[k]:
    print(line)

output:

-------
 # is
-------
#:  Two before narrow not relied how except moment myself.

#:  Ham followed now ecstatic use speaking exercise may repeated Himself he evident oh
    greatly my on inhabit general concern.

-------
 % is
-------
%:  So gate at no only none open. Betrayed at properly it of graceful on
    Dinner abroad am depart ye turned hearts as me wished.

%:  Therefore allowance too perfectly gentleman supposing man his now
    Families goodness all eat out bed steepest servants.

Try this,

with open("text.txt", "r") as f:
  lines = f.readlines()

  for k, g in itertools.groupby(lines, lambda line:line.strip() == ""):
    line = "".join(g).strip()
    if line.startswith("#"):
      print(line)

Firstly I group all the lines that come between two "\n", then join them into one sentence and check which one starts with #.

Related