Skip to main content
 首页 » 编程设计

python之正则表达式排除由引号和以 % 开头的行包围的匹配项

2024年09月03日25yyy_WW

我想制作一个能够执行以下操作的正则表达式:

  • 准确匹配各种词,例如{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') 没有成功的原因。