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