Pulling a list of lines out of a string - python-3.x

Beginning
Line 2
Line 3
Line 4
Line 5
Line 6
End
Trying to pull off line 2 through line 6. Can't do it to save my soul.
a is the saved string I'm searching through.
b = re.findall(r'Beginning(.*?)End', a)
Doesn't give me a thing, just a blank b. I know it's because of the newlines but how do I go about detecting and moving on forward with the newlines. I've tried, not knowing exactly for sure how I'm suppose to use MULTILINE or DOTALL. Nothing changed.
How do I go about getting it to put lines 2 through 6 in b?
To add in this will occur multiple times through the same file that I need to perform this search and pull technique. I have no other easy way of doing this since the information in Lines 2-6 need to be looked through further to pull off data that will be put into a csv file. Since some of the data contains hours and some of the data doesn't contain hours, aka Unavailable, I need to be able to pull off and differentiate between the two occurrences.

string = """Beginning
Line 2
Line 3
Line 4
Line 5
Line 6
End
"""
lines = string.splitlines()
answer = []
flag = False
for line in lines:
line = line.strip()
if not line: continue
if line == "Beginning":
flag = True
continue
if line == "End": flag = False
if not flag: continue
answer.append(line)
Output:
In [209]: answer
Out[209]: ['Line 2', 'Line 3', 'Line 4', 'Line 5', 'Line 6']

You could make a function that takes a multi-line string, then a starting line, and an ending line.
def Function(string, starting_line, ending_line):
if "\n" in string: #Checks for whether or not string is mult-line
pass
else:
return "The string given isn't a multiline string!" #If string isn't multiline, then Function returns a string explaining that string isn't a multi-line string
if ending_line < starting_line: #Checks if ending_line < starting_line
return "ending_line is greater than starting_line!" #If ending_line < starting_line, then Function returns a string explaining that ending_line > starting_line
array = [] #Defines an array
for i in range(len(string)): #Loops through len(string)
if list(string)[i] = "\n": #Checks whether list(string)[i] = a new line
array.append(i) #Appends i to array
return string[array[starting_line - 1]::array[ending_line - 1]]
print(Function(a, 3, 7))
This code should return:
Line 1
Line 2
Line 3
Line 4
Line 5
Line 6

Related

Checking to see if the 1, 2 and 3rd element in a list is an integer Python 3

I have a line that I stripped and split into strings. I checked to see if the first element in the list is indeed the string I am looking for. Now I need to check if elements 1 to 2 in the list are integers 0-9 (inclusive) This is what I have so far, but I feel like there must be a cleaner way to write this.
for line in sys.stdin:
line = line.strip() #strips line of whitespace
line = line.split() #splits line into strings
if not line[0].startswith("#"): #if line does not begin with #comment, it will read in
if line[0] == "init" and line[1].isnumeric() and line[2].isnumeric():
wid = int(line[1])
hei = int(line[2])
init(wid, hei)
else:
print("Input error: Faulty init(value, value) Command ")
sys.exit() #terminates program

How to skip N central lines when reading file?

I have an input file.txt like this:
3
2
A
4
7
B
1
9
5
2
0
I'm trying to read the file and
when A is found, print the line that is 2 lines below
when B is found, print the line that is 4 lines below
My current code and current output are like below:
with open('file.txt') as f:
for line in f:
if 'A' in line: ### Skip 2 lines!
f.readline() ### Skipping one line
line = f.readline() ### Locate on the line I want
print(line)
if 'B' in line: ## Skip 4 lines
f.readline() ### Skipping one line
f.readline() ### Skipping two lines
f.readline() ### Skipping three lines
line = f.readline() ### Locate on the line I want
print(line)
'4\n'
7
'1\n'
'9\n'
'5\n'
2
>>>
Is printing the values I want, but is printing also 4\n,1\n... and besides that, I need to write several f.realines()which is not practical.
Is there a better way to do this?
My expected output is like this:
7
2
Here is a much simpler code for you:
lines=open("file.txt","r").read().splitlines()
#print(str(lines))
for i in range(len(lines)):
if 'A' in lines[i]:
print(lines[I+2]) # show 2 lines down
elif 'B' in lines[i]:
print(lines[I+4]) # show 4 lines down
This reads the entire file as an array in which each element is one line of the file. Then it just goes through the array and directly changes the index by 2 (for A) and 4 (for B) whenever it finds the line it is looking for.
if you don't like repeated readline then wrap it in a function so the rest of the code is very clean:
def skip_ahead(it, elems):
assert elems >= 1, "can only skip positive integer number of elements"
for i in range(elems):
value = next(it)
return value
with open('file.txt') as f:
for line in f:
if 'A' in line:
line = skip_ahead(f, 2)
print(line)
if 'B' in line:
line = skip_ahead(f, 4)
print(line)
As for the extra output, when the code you have provided is run in a standard python interpreter only the print statements cause output, so there is no extra lines like '1\n', this is a feature of some contexts like the IPython shell when an expression is found in a statement context, in this case f.readline() is alone on it's own line so it is detected as possibly having a value that might be interesting. to suppress this you can frequently just do _ = <expr> to suppress output.

How to nest a conditional 3 quote strings inside another 3 quote strings in python?

I am trying to a paragraph of lines using 3 quote strings where some group of lines in the paragraph are to be included on a if condition. I am using {} brackets for those conditional lines and since each of them have to be on the next line, I have to use 3 quote strings for them. So its a nested 3 quote string with a condition
For example, I have
write_line_3nd4 = True
paragraph = f'''
this is line one
x = 12 #line two
{f'''
line 3,4 #this is line 3
x=34 #this is line 4''' if write_line_3nd4 else ''}
'''
It gives me an error as such:
File "<ipython-input-36-4bcb98c8ebe0>", line 6
line 3,4 #this is line 3
^
SyntaxError: invalid syntax
How do use conditional multi-line strings inside multi-line strings?
In the future, simplify your question down to the most basic form. I am not sure if I understand you correctly but I am assuming you only want to print your line 3 and line 4 if "write_line_3nd4 = True"
It is much simpler to put your conditional outside of the string and then append the result inside. I have edited your code to do this:
write_line_3nd4 = True
if write_line_3nd4 == True:
line3 = '3,4'
line4 = 'x=34'
else:
line3 = ''
line4 = ''
paragraph = f'''
this is line one
x = 12
''' + line3 + '''
''' + line4
EDIT: If you insist on putting your conditionals inside your multi-line string, you could do it using inline expressions. This is what it would look like:
write_line_3nd4 = True
paragraph = f'''
this is line one
x = 12
''' + ('3,4' if write_line_3nd4 == True else '') + '''
''' + ('x=34' if write_line_3nd4 == True else '')
Maybe this will help.
x = "one"
if x == "one":
y = "two"
else:
y = "three"
print("""
This is some line of printed text
This is some line of printed more text
these {} and {} are variables designated by `str.format()`
""".format(x, y))
print(x)
Im not sure what you're asking either but this is my guess as to what you are looking for.

remove the item in string

How do I remove the other stuff in the string and return a list that is made of other strings ? This is what I have written. Thanks in advance!!!
def get_poem_lines(poem):
r""" (str) -> list of str
Return the non-blank, non-empty lines of poem, with whitespace removed
from the beginning and end of each line.
>>> get_poem_lines('The first line leads off,\n\n\n'
... + 'With a gap before the next.\nThen the poem ends.\n')
['The first line leads off,', 'With a gap before the next.', 'Then the poem ends.']
"""
list=[]
for line in poem:
if line == '\n' and line == '+':
poem.remove(line)
s = poem.remove(line)
for a in s:
list.append(a)
return list
split and strip might be what you need:
s = 'The first line leads off,\n\n\n With a gap before the next.\nThen the poem ends.\n'
print([line.strip() for line in s.split("\n") if line])
['The first line leads off,', 'With a gap before the next.', 'Then the poem ends.']
Not sure where the + fits in as it is, if it is involved somehow either strip or str.replace it, also avoid using list as a variable name, it shadows the python list.
lastly strings have no remove method, you can .replace but since strings are immutable you will need to reassign the poem to the the return value of replace i.e poem = poem.replace("+","")
You can read all non-empty lines like this:
list_m = [line if line not in ["\n","\r\n"] for line in file];
Without looking at your input sample, I am assuming that you simply want your white spaces to be removed. In that case,
for x in range(0, len(list_m)):
list_m[x] = list_m[x].replace("[ ](?=\n)", "");

Python program for json files

i want to search a particular keyword in a .json file and print 10 lines above and below the line in which the searched keyword is present.
Note - the keyword might be present more than once in the file.
So far i have made this -
with open('loggy.json', 'r') as f:
last_lines = deque(maxlen=5)
for ln, line in enumerate(f):
if "out_of_memory" in line:
print(ln)
sys.stdout.writelines(chain(last_lines, [line], islice(f, 5)))
last_lines.append(line)
print("Next Error")
print("No More Errors")
Problem with this is - the number of times it prints the keyword containing line is equal to that number of times the keyword has been found.
it is only printing 5 lines below it, whereas i want it to print five lines above it as well.
If the json file was misused to store really a lot of information, then
processing on-the-fly may be better. In the case, keep the history lines
say in the list that is shortened if it grows above a given limit.
Then use a counter that indicates how many lines must be displayed after
observing a problem:
#!python3
def print_around_pattern(pattern, fname, numlines=10):
"""Prints the lines with the pattern from the fname text file.
The pattern is a string, numline is the number of lines printed before
and after the line with the pattern (with default value 10).
"""
history = []
cnt = 0
with open(fname, encoding='utf8') as fin:
for n, line in enumerate(fin):
history.append(line) # append the line
history = history[-numlines-1:] # keep only the tail, including last line
if pattern in line:
# Print the separator and the history lines including the pattern line.
print('\n{!r} at the line {} ----------------------------'.format(
pattern, n+1))
for h in history:
print('{:03d}: {}'.format(n-numlines, h), end='')
cnt = numlines # set the counter for the next lines
elif cnt > 0:
# The counter indicates we want to see this line.
print('{:03d}: {}'.format(n+1, line), end='')
cnt -= 1 # decrement the counter
if __name__ == '__main__':
print_around_pattern('out_of_memory', 'loggy.json')
##print_around_pattern('out_of_memory', 'loggy.json', 3) # three lines before and after

Resources