我想制作一个能够执行以下操作的正则表达式:
- 准确匹配各种词,例如{
addpaths,addpath,test} - 排除以
%符号开头的行 - 排除用引号括起的匹配项(
'和")
所以我想出了以下正则表达式(带有标志 g、m):
^[^%]*?(?<=[^\'\"])\b(addpaths|addpath|test)\b(?=[^\'\"]).*?$?
这给了我以下结果(参见 regex101 ):
function addpaths() --> match, correct
% function addpaths to add paths to path --> no match, correct
fprintf('running addpaths') --> no match, correct
fprintf('addpaths running') --> no match, correct
fprintf('running addpaths.') --> match, wrong
fprintf('running addpaths function') --> match, wrong
% fprintf('running addpaths') --> no match, correct
% fprintf('addpaths running') --> no match, correct
% fprintf('running addpaths function') --> no match, correct
% test what happens to 'test' --> no match, correct
run('test') --> no match, correct
'this is a test.' --> match, wrong
test --> match, correct
因此,当其中一个完全匹配的词紧挨着 ' 时正则表达式起作用,但当它旁边有另一个词、空格或 . 时则不起作用。为什么?
import re
text = '''function addpaths()
% function addpaths to add paths to path
fprintf('running addpaths')
fprintf('addpaths running')
fprintf('running addpaths function')
% fprintf('running addpaths')
% fprintf('addpaths running')
% fprintf('running addpaths function')
% test what happens to 'test'
run('test')
'this is a test.'
test
'''
pattern = '^[^%]*?(?<=[^\'\"])\\b(addpaths|addpath|test)\\b(?=[^\'\"]).*?$'
regex = re.compile(pattern, re.M)
matches = regex.findall(text)
for m in matches:
print(m)
请您参考如下方法:
试试这个:
import re
text = '''function addpaths()
% function addpaths to add paths to path
fprintf('running addpaths')
fprintf('addpaths running')
fprintf('running addpaths function')
% fprintf('running addpaths')
% fprintf('addpaths running')
% fprintf('running addpaths function')
% test what happens to 'test'
run('test')
'this is a test.'
test'''
pattern = r"""^(?!\s*%)[^'\"]+?\b(addpaths|addpath|test)\b(?!.*?['\"]).*?$"""
regex = re.compile(pattern, re.M)
for line in text.split('\n'):
print(line.ljust(50, ' '), regex.match(line) and 'OK' or 'NO MATCH')
输出:
function addpaths() OK
% function addpaths to add paths to path NO MATCH
fprintf('running addpaths') NO MATCH
fprintf('addpaths running') NO MATCH
fprintf('running addpaths function') NO MATCH
NO MATCH
% fprintf('running addpaths') NO MATCH
% fprintf('addpaths running') NO MATCH
% fprintf('running addpaths function') NO MATCH
NO MATCH
% test what happens to 'test' NO MATCH
run('test') NO MATCH
'this is a test.' NO MATCH
test OK
我使用了 negative lookahead (?!.*?['\"]) 因为 'this is a test.' 在单词 test 有 . 但在你 regex (addpaths|addpath|test)\b(?=[^\'\"]) 您排除了直接跟在引号后的文本。这就是为什么 run('test') 没有成功的原因。
