Как указать, что не соответствовать на регулярное выражение - PullRequest
0 голосов
/ 22 октября 2018

Отказ от ответственности: этот вопрос был переделан, поэтому комментарии и ответы могут показаться не связанными.Я извиняюсь, но я сделал это ради более ясного и лучше структурированного вопроса.

Предположим, задана строка, в которой я хочу найти две разные группы (имен), где одна группа A удовлетворяет условию1 и группа B удовлетворяет условию 2, но также и условию 1.

Для примера: скажем, у меня есть математическая функция -

'[class.parameterA] * numpy.exp( [x]*module.constantA - constant_B/[x] ) + [parameter_B]'

- где я контролирую значения параметровно не для констант.Я хочу получить (используя re.findall()) группу для констант и группу для параметров.

>>> group1
['numpy.exp', 'module.constantA', 'constant_B']
>>> group2
['class.parameterA', 'x', 'x', 'parameter_B']

Я знаю, что для этого конкретного случая я не должен соответствовать numpy.exp, но дляради цели вопроса, я позволю ему быть совпадением.

Чтобы уточнить, этот вопрос направлен на то, чтобы искать представление "игнорировать сопоставление {sequence}" в регулярном выражении и знать, есть лиэто возможность подойти к проблеме "ТОЛЬКО условие 1", а не "удовлетворять условие 1, а НЕ условие 2", поэтому решение можно распространить на несколько условий. Пожалуйста, предоставьте частично абстрагирующий ответ (не одинэто слишком специфично для этого примера).

Через некоторое время, конечно, мне удалось найти частичное решение (см. bonus ) только для одной из групп, но любой другойочень приветствуются ясные из них:

c1 = r'\w+\.?\w*' # forces alphanumeric variable structure
# c1 = r'[\w\.\(\)]*?' allows more freedom (can introduce function calls)
# at the cost of matching invalid names, like class..parameterA
c2 = r'(?<=\[)', r'(?=\])'

re_group2 = c2[0] + c1 + c2[1]

>>>> re.findall(re_group2, func)
['class.parameterA', 'x', 'x', 'parameter_B']

Очевидно, что интуитивно понятное отрицание скобок не работает для group1, но я могу неправильно его ввести:

c1 = r'\w+\.?\w*'
nc2 = r'(?<!\[\w)', r'(?!\w\])' # condition 2 negation approach

re_group1 = nc2[0] + c1 + nc2[1]

>>> re.findall(re_group1, func)
['class.parameterA', 'numpy.exp', 'x', 'module.constantA',
'constant_B', 'x', 'parameter_B']

Бонус : если бы, скажем, было module.submodule.constantA (более 1 точки), как бы изменилось регулярное выражение?Я предположил c1 = r'\w+(\.\w+)*', но это не так, как я ожидал.Изменить: мне нужно использовать группу без захвата, так как я использую re.findall.Итак c1 = r'\w+(?:\.\w+)*'.

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Использовать double findall будет здорово.

import re
a = "rho_1 * x + R * [np.R] + rho_1 / x + R * [np.R]"

print(re.findall(r"\w+(?= \*| \/)",a))
print(re.findall("(?<=\[).*?(?=\])",a))
  1. Группа 1
    • \ w + Соответствует не алфавитно-цифровому символу, исключая "_"
    • (? = * | /) конец строки * или /
  2. Группа 2
    • (? <= [) начинаются с <code>[
    • . *?соответствует любому символу как можно меньше
    • (? =]) заканчивается ]
0 голосов
/ 22 октября 2018

Я сделал два изменения: я закрепил поиск в начале слова и преобразовал ваше первое утверждение в просмотр сзади.Я попробовал это в Notepad ++ (здесь нет Python), и это сработало для образца

\b(?<!\[)[a-wzA-Z_0-9]+(?!\])

Надеюсь, ваши формулы имеют одинаковый интервал ...

...