Регулярные выражения: как использовать «или» без дополнительных групп захвата?

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

expression1 | expression2

Сценарий считает, что существует 6 групп захвата (каждое выражение содержит 3 группы захвата), и поэтому выдает ошибку.

Как мне объединить 2 выражения, чтобы скрипт не думал, что есть 6 групп захвата, потому что оба выражения никогда не могут быть применены, это либо выражение1, либо выражение2, но никогда оба одновременно.

Выражения1:

([a-zA-Z0-9]+[ ]?)\(P[: ]?([a-zA-Z0-9 ]*)()

Выражения2:

()()\)[ ]+([a-zA-Z0-9]+$|[a-zA-Z0-9]+[ ])

Спасибо за любые предложения!


person Saeko    schedule 16.02.2018    source источник
comment
Используется ли библиотека регулярных выражений re или regex?   -  person Wiktor Stribiżew    schedule 16.02.2018
comment
Единственная библиотека для скрипта — re.   -  person Saeko    schedule 16.02.2018
comment
Для re не существует универсального решения. Саеко, выложи, пожалуйста, актуальные выкройки.   -  person Wiktor Stribiżew    schedule 16.02.2018
comment
Я не знаю, можно ли кратко и выразительно записать логику исключающего ИЛИ в регулярном выражении Python. Похоже, изменить логику кода было бы проще.   -  person Cong Ma    schedule 16.02.2018
comment
Выражение1: ([a-zA-Z0-9]+[ ]?)(P[: ]?([a-zA-Z0-9 ]*)() Выражение2: ()())[ ] +([a-zA-Z0-9]+$|[a-zA-Z0-9]+[ ])   -  person Saeko    schedule 16.02.2018
comment
@Saeko, не могли бы вы обновить свой пост выражениями, пожалуйста.   -  person Nahuel Fouilleul    schedule 16.02.2018
comment
@Cong Ma К сожалению, это для школьного проекта, и когда я редактирую что-то еще в сценарии, ожидаю регулярное выражение и пытаюсь его загрузить, школьная система не принимает его, потому что файл редактируется в местах, где это не так. должно быть отредактировано   -  person Saeko    schedule 16.02.2018
comment
Как работает эта школьная система? Они действительно просили вас создать такое регулярное выражение? Кажется таким бессмысленным. Если нет, то что такого особенного в этой строке, что она единственная, которую можно редактировать?   -  person ndnenkov    schedule 16.02.2018
comment
Это для курса под названием «Язык сценариев», мы должны были начать с основ Python, но вместо этого начали с Regex... что было бы не так уж плохо, но этот проект, похоже, сосредоточен на том, чтобы сделать регулярные выражения настолько сложными насколько это возможно по-человечески. Мы получили полный скрипт с несколькими точками, которые нужно было заменить регулярными выражениями, и мы можем проверить, работает ли наш скрипт на их веб-сайте, который также проверяет, был ли скрипт каким-либо образом отредактирован.   -  person Saeko    schedule 16.02.2018


Ответы (2)


РЕДАКТИРОВАТЬ: после обновления сообщения, поскольку группы 1 и 2 пусты во втором выражении, а группа 3 пуста в первом, их следует объединить с группой без захвата и просто удалив пустые группы:

(?:([a-zA-Z0-9]+[ ]?)\(P[: ]?([a-zA-Z0-9 ]*)|\)[ ]+([a-zA-Z0-9]+$|[a-zA-Z0-9]+[ ]))

Также последнюю группу ([a-zA-Z0-9]+$|[a-zA-Z0-9]+[ ]) можно сократить

([a-zA-Z0-9]+(?:$|[ ]))

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

без дополнительной информации о выражении1 и выражении2 трудно ответить, предположим, что шаблоны имеют следующую форму:

exp1: (g11)s11(g21)s21(g31)
exp2: (g12)s12(g22)s22(g32)

комбинированное выражение может быть

(?=(?:g11)s11(?:g21)s21(?:g31)|(?:g12)s12(?:g22)s22(?:g32))((?:g11|g12))(?:s11|s12)((?:g21|g22))(?:s21|s22)((?:g31|g32))

но это может быть упрощено в зависимости от того, что требуется.

person Nahuel Fouilleul    schedule 16.02.2018

У вас есть 2 нормальные альтернативы и несколько плохих:

Первый нормальный. отдельно через код:

if (expression1) {
    DO SOMETHING
} else if (expression2) {
    DO SOMETHING
} else {
    NO MATCH FOR BOTH
}

Второй нормальный. Работа со всеми 6 карманами.

if (arMatches[1] or arMatches[2] or arMatches[3]) {
    DO SOMETHING
} else if (arMatches[4] or arMatches[5] or arMatches[6]) {
    DO SOMETHING
} else {
    NO MATCH FOR BOTH
}

Для плохих решений вы можете использовать очень сложное регулярное выражение, которое, вероятно, будет иметь некоторые скрытые ошибки, и это выражение будет ОЧЕНЬ сложно поддерживать, возможно, вообще невозможно.

person A. Denis    schedule 16.02.2018