Filip Pawelec
Filip Pawelec

Reputation: 63

String index out of range python 3.7

I'm trying to write a function for a text rpg game that would print on terminal everything that is in specific marker, but I keep getting this error message:

IndexError: string index out of range

Marked text in a file looks like this:

|d0Dyspergator: "Pulvis es et in pulverem revertis" Raz na dwie walki i tylko raz w walce pozwala na uniknięcie następnego ataku przeciwnika poprzez chwilowe zamienienie Cię w atomowy pył.|

where the pipe and first two symbols after it begin the marker, next pipe ends it. Here is the code:

def bard(paragraph, point, file):
    with open(file, 'r', encoding='utf-8') as w:
        d = w.read()
        index = 0
        tab = []
        frag = 0
        while frag == 0:
            if d[index] == '|'and d[index + 1] == paragraph and d[index + 2] == point:
                while d[index+3] != '|' and index + 3 <= len(d):
                    tab.append(d[index+3])
                    index += 1
                frag += 1
            else:
                index += 1
        a = ''.join(tab)
        print(a)
    return

I would be very thankful for any help, I am new to programming and I probably made a stupid mistake.

Upvotes: 1

Views: 91

Answers (2)

JosefAssad
JosefAssad

Reputation: 4128

Assuming that a) this data structure with the piles and initial two (and exactly two) characters is a format you have developed yourself, and you control that it is consistently used, then you don't really need to go to any lengths least of all resort to regular expressions.

foo = '|d0Dyspergator: "Pulvis es et in pulverem revertis" Raz na dwie walki i tylko raz w walce pozwala na uniknięcie następnego ataku przeciwnika poprzez chwilowe zamienienie Cię w atomowy pył.|'
foo.split('|')[1][2:]
'Dyspergator: "Pulvis es et in pulverem revertis" Raz na dwie walki i tylko raz w walce pozwala na uniknięcie następnego ataku przeciwnika poprzez chwilowe zamienienie Cię w atomowy pył.'

Upvotes: 0

Patrick Artner
Patrick Artner

Reputation: 51643

You are trying to do pattern matching on text. Ever heard of regular expression?

It is exactly what they are build for:

text = """This is some text.
|2. second 
thing| more text
|3. thingding is after the marker and this text also.
This texts ends what I want| and this text should not be found..
also not found."""
with open("t.txt","w") as  f: 
    f.write(text)

Program:

with open("t.txt") as r:
    data = r.read()

import re
pattern = r'\|\d+\..*?\|'
k = re.findall(pattern,data,re.MULTILINE|re.DOTALL)

print(k)

Output:

['|2. second \nthing|', 
 '|3. thingding is after the marker and this text also.\nThis texts ends what I want|']

The pattern r'\|\d+\..*?\|' I use looks for:

\|          matches the character | literally (case sensitive)
\d+         matches a digit (equal to [0-9])
    +           Quantifier — one to unlimited times, as many as possible
\.          matches the character . literally (case sensitive)
.*?         matches any character 
    *?          Quantifier — zero to unlimited times, as few as possible 
\|          matches the character | literally (case sensitive)

You can play around with it here: https://regex101.com/r/65R2gq/1/

If you only need the text, you can use capturing groups - change the pattern to

pattern = r'\|\d+\.(.*?)\|'

to get

[' second \nthing', 
 ' thingding is after the marker and this text also.\nThis texts ends what I want']

Upvotes: 3

Related Questions