0

My code reads through a parsed text file line by line. I am trying to pull a list of fault codes using my reg expression. My problem is that when I include my regex in my if statement, I am not receiving my desired text.

The regex "[:fault]_+[\d|\D]_+[\d|\D]_+[\d|\D]+[Type\S]" should return a fault code such as :

fault_0A_01_00 Type:Warning, triggered. 

Building a list of faults and using this function. I am able to pull my faults. However I did away with this list and decided a regex would be a better option to find the faults rather than having to update my fault list from time to time

def find_fault(self, fault):
    count = 0
    l_fault = fault
    with open(self.file) as f:
        for line in f.readlines():
            if l_fault in line: 
                count += 1
    self.fault_dict[l_fault] = count

Here is my loop that does not return my desired text based off my regex

def find_fault(self, fault):
    count = 0
    l_fault = fault
    regex_txt = r"[:fault]_+[\d|\D]_+[\d|\D]_+[\d|\D]+[Type\S]"
    #pattern = re.compile(regex_txt, re.IGNORECASE)
    with open(self.file) as f:
        for line in f.readlines():
            if l_fault in regex_txt:
                count =+ 1
            else:
                return -1
    self.fault_dict[fault] = count

Right now using the regex inside the loop and using the if statement, my dictionary of faults returns as:

 {'a': 1, 'e': 1, 'd': 1, 'l': 1, 'p': 1, 'u': 1, 't': 1, 'y': 1, '_': 1, 'D': 1}

My expectations are something such as:

{':fault_01_00_00': 1, ':fault_01_00_01': 1, ':fault_01_00_02': 1, ':fault_01_00_03': 1, ':fault_01_00_04': 1, ':fault_01_00_05': 1, ':fault_01_00_06': 1, ':fault_01_00_07': 1, ':fault_01_00_08': 1, ':fault_01_00_09': 1}
Saleem Ali
  • 1,213
  • 8
  • 19
cinemod
  • 27
  • 5

2 Answers2

2

You never apply your regex to the string line. You need to apply it using e.g. `faults = re.findall(regex_txt, line)´:

with open(self.file) as f:
    for line in f.readlines():
        faults = re.findall(regex_txt, line) #returns list of found strings
        if l_fault in faults:
            count =+ 1
        else:
            return -1
LeoE
  • 1,803
  • 1
  • 6
  • 21
  • and btw I think the regex you wanted is more like this: `r":fault_[\d|\D]{2}_[\d|\D]{2}_[\d|\D]{2}"` Assuming, that you expect your keys to be e.g. `':fault_01_00_01'`. Using your regex it results in `':fault_0A_01_00 Type:Warning, triggered. '`. See [yours](https://regex101.com/r/82cXQ3/1) and the [new](https://regex101.com/r/82cXQ3/2) regex. – LeoE Oct 07 '19 at 14:28
  • Also your regex includes all characters after Type\S since you simply put a [\d|\D]+ close to the end resulting in any number of digits or letters allowed. – LeoE Oct 07 '19 at 14:35
0

You're regex_txt (your pattern) is not set up correctly. When you use [fault], you're saying you are looking for one character which is either f, a, u, l or t.

You'd also have to specify how many digits you are looking for. In the test string you provided ':fault_0A_01_00 Type:Warning, triggered', there are two digits in a row. Assuming you'd expect either 1 or 2 digits, you'd have to put \d+. The + indicates that you're looking for either 1 or 2 elements.

Zephyrus
  • 255
  • 1
  • 8
  • using [:fault] **+** however actually works (not the best thing to do though) and also the digits do work, however probably not in the way expected by @cinemod. See my comment on my answer with he regarding links. – LeoE Oct 07 '19 at 14:33
  • Yes, you're right! However, cinemod used `[:fault]_+` and `[\d|\D]_+` which doesn't work (hence my confusion). – Zephyrus Oct 07 '19 at 15:02