简体   繁体   中英

Python re.sub not working with colorama and re.compile

I have the following program which searches for a string in lines in a certain location and then outputs the search matches. I want to be able to choose whether to ignore case in the search and highlight the search string in the output line.

import re, os, glob  
from colorama import init, Fore, Back, Style  
init(autoreset=True)

path = "c:\\temp2"  
os.chdir(path) 

def get_str(msg):
    myinput = input(msg)
    while True:
        if not bool(myinput):
            myinput = input('No Input..\nDo it again\n-->')
            continue
        else:
            return myinput

ext = get_str('Search the files with the following extension...')
find = get_str('Search string...')
case = get_str('    Ignore case of search string? (y/n)...')   
print()

if case == "y" or case == "Y":
    find = re.compile(find, re.I) 
else:
    find = find

files_to_search = glob.glob('*.' + ext)

for f in files_to_search:
    input_file = os.path.join(path, f)
    with open(input_file) as fi:
        file_list = fi.read().splitlines() 
        for line in file_list:
            if re.search(find, line):  
                line = re.sub(find, Fore.YELLOW + find + Fore.RESET, line)
                print(f, "--", line) 

The program works if I select "n" for case. If I select "y" I get this error when the program is run:

Search the files with the following extension...txt  
Search string...this  
    Ignore case of search string? (y/n)...y  

Traceback (most recent call last):  
  File "C:\7. apps\eclipse\1. workspace\learning\scratch\scratchy.py", line 36, in <module>
    line = re.sub(find, Fore.YELLOW + find + Fore.RESET, line)  
TypeError: Can't convert '_sre.SRE_Pattern' object to str implicitly   

How can I make this work for the "yes" case?

The issue has to do with the string concatenation you're doing in your re.sub call. The expression Fore.YELLOW + find + Fore.RESET isn't valid if find is a compiled regular expression object instead of a string.

To fix this, I suggest using a different variable name for the regular expression pattern than you use for the original string:

if case == "y" or case == "Y":
    pattern = re.compile(find, re.I)
else:
    pattern = find

Then pass pattern as the first argument to re.sub . find will remain a string in all cases, so it will work in expression in the second argument:

line = re.sub(pattern, Fore.YELLOW + find + Fore.RESET, line)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM