Регулярное выражение исключает совпадения, заключенные в кавычки и строки, начинающиеся с% - PullRequest
2 голосов
/ 15 октября 2019

Я хочу создать регулярное выражение, способное выполнять следующие действия:

  • Точно сопоставлять различные слова, например {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)

1 Ответ

2 голосов
/ 15 октября 2019

Попробуйте:

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')

OUPUT:

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') не мах

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...