正则表达式字符串匹配-潜在的反斜杠问题

时间:2020-03-02 19:54:51

标签: python regex python-3.x

我对Python相对较新,但是马上就可以使用。我试图找出为什么我的字符串不能正确匹配的原因。基本上,我正在评估一个文本文件,以查看是否存在注册表项和路径。当然,这不是您见过的最性感的代码,但这是执行正则表达式检查的功能:

     def stigeval (content, regex1, regex2):
        # Now set the registry key path and value
        regex = re.compile(regex1, re.IGNORECASE)

        match = re.search(regex, content)
        if match != None:
            findex = match.start()
            regpathpass = True
            regex = re.compile(regex2, re.IGNORECASE)
            match = re.search(regex, content)
            if match != None:
                findex = match.start()
                regkeypass = True
            else:
                regkeypass = False
        else:
            regpathpass = False
            regkeypass = False

        return(regpathpass, regkeypass)

这是我要传递的功能:

cregex1 = r'(HKEY_CURRENT_USER\\|HKCU\\|HKCU:\\)\\Software\\Policies\\Microsoft\\Office\\14\.0\\word\\security\\fileblock'
            cregex2 = r'Word97Files\s*=\s*5'

            status = stigeval(content, cregex1, cregex2)

这是内容:

01/14/2020 16:28:20
Temp
 HKCU:\\Software\Policies\Microsoft\Office\14.0\word\security\fileblock\Word97Files = 5.

根据我的评估,正则表达式应该与上面的键匹配,但是由于某种原因它返回False。我确定这是因为我错过了一些东西。我问题的症结在于没有进行比赛。

findex = re.search(regex, content).start()
AttributeError: 'NoneType' object has no attribute 'start'

2 个答案:

答案 0 :(得分:1)

已编译模式的标志应该传递给re.compile

您的代码很难阅读和遵循,对于这样简单的任务也太复杂了。

尝试通过预先捕获错误来避免不必要的try块:

match = re.search(regex, content)
if match != None:
    findex = match.start()

还可以通过处理更简单的else情况来避免嵌套if语句

if findex < 0:
    return
regex = ...

仅当您打印错误时,所有这些情况都可以避免:

except Exception as e:
    print(e) # cannot process flags argument with a compiled pattern

答案 1 :(得分:1)

我注意到,检查match.start()的结果是否大于0并不表示找到了匹配项,实际上是找到了。

>>> cregex1 = r'(HKEY_CURRENT_USER\\|HKCU\\|HKCU:\\)\\Software\\Policies\\Microsoft\\Office\\14\.0\\word\\security\\fileblock'
>>> m = re.search(cregex1, s, re.IGNORECASE)
>>> m.start()
0
>>> m.group(0)
'HKCU:\\\\Software\\Policies\\Microsoft\\Office\\14.0\\word\\security\\fileblock'
>>> 

正则表达式应用于

>>> print(s)
HKCU:\\Software\Policies\Microsoft\Office\14.0\word\security\fileblock\Word97Files = 5.
>>> 

因此,在这段代码中,匹配成功,但是if findex > 0并不是成功的良策,因为当match.start()将会是0时,找到匹配项。

    findex = re.search(regex, content, re.IGNORECASE).start()
except:
    print('Registry path not found')
    findex = 0
if findex > 0:
    # An index matching the string was found
    regpathpass = True

此函数可以这样重写:

# Elsewhere in code - maybe top of the file with other "constants".
REG_KEY_HKCU_OFF_FILEBLOCK = re.compile(<expr here>, re.IGNORECASE)
REG_KEY_WORD_FILES         = re.compile(<expr here>, re.IGNORECASE)

def stigeval(content, regex1, regex2):
    # Now set the registry key path and value (??)
    regpathpass = False
    regkeypass  = False
    try:
        regpathpass = regex1.search(content) != None
        if regpathpass:
            regkeypass = regex2.search(content) != None
    except re.error as err:
        print(f'Registry path not found due to error in expression: {err}')
        raise err  # You can do this if you want the error to go 
                   # up the call stack after you've printed the helpful
                   # message.

    return (regpathpass, regkeypass)

假定正则表达式expr所搜索的文本值得作为常量(经常不变的重用),我将它们已经编译在顶部。可以在调用func时将它们作为参数传递。

该函数假定已经编译的正则表达式为params。如果传递给此函数的键发生了很大变化,则为它们提供常量是没有意义的。然后,只需在函数内部使用re.search(<regex>...)-不要浪费编译周期,因为它们仅使用一次。

正如其他回答用户所指出的那样,try/except块应包含尽可能多的代码,而不是单个调用-如果可能。我知道情况并非总是如此。但是在这种情况下,您可以在try/except中放入很多代码,从而大大简化您的功能。

另一位用户评论说except:不能捕获特定异常在这种情况下是危险的,因为无论发生什么情况,日志输出都是“找不到路径”。更好的策略是捕获特定的错误表达式,并将其消息包含在输出中,或者允许错误被抛出调用堆栈,以便开发人员知道发生了他们无法预测的其他错误类型。

相关问题