Как сопоставить строку, которая начинается хотя бы с одного из k и может содержать несколько ключевых слов в любом порядке - PullRequest
0 голосов
/ 22 апреля 2020

k1, k2, ..., kn ключевые слова. Например, учитывая k1, k2, k3 мне нужно сопоставить все последующие вхождения.

k1
k2
k3
k1k2
k1k3
k2k1
k2k3
k3k1
k3k2
k1k2k3
k1k3k2
k2k1k3
k2k3k1
k3k1k2
k3k2k1

Logi c Я должен создать регулярное выражение для каждой перестановки k1, k2, ..., kn (n - переменная). Однако это приводит к факторному количеству регулярных выражений - 3! в приведенном выше примере k1(k2)?(k3)?, k1(k3)?(k2)?, k2(k1)?(k3)?, k2(k3)?(k1)?, k3(k1)?(k2)?, k3(k2)?(k1)? при последовательном запуске на одной и той же строке получат все вышеперечисленные совпадения.

Как это можно сделать более эффективным?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Регулярные выражения распознают обычные языки. Ваш язык конечный , поэтому он является регулярным по определению (вы можете написать для него регулярное выражение, объединив все слова с | между ними), но для обычных языков характерно повторения шаблонов . Конечный язык не может иметь произвольных повторений, что означает, что в вашем регулярном выражении не может быть *. Так что это не очень традиционный обычный язык. В некоторых случаях регулярное выражение для языка, в частности для конечного языка, не может быть на намного проще, чем просто перечисление всех строк языка. Это один из таких случаев. У языка есть структура, но это не структура, основанная на повторениях, поэтому сила регулярных выражений просто не соответствует задаче /

Если вы посмотрите на сложность, которая вам нужна в вашем регулярном выражении (или конечно) конечный автомат, еще один способ сопоставления с обычными языками), чтобы распознать строки вашего языка, вы можете посмотреть информацию, которую вы должны запомнить, увидев любой префикс строки.

Чтобы распознать k1k2k3k4 и отклоните k1k2k3k1, k1k2k3k2 и k1k2k3k3, информация, которую вы должны запомнить после просмотра k1k2k3, это то, что вы видели k1, k2 и k3. Таким образом, для любой последовательности ключевых слов вы должны помнить точное подмножество ключевых слов , которое было замечено до сих пор. Это примерно экспоненциальная длина видимой строки.

Если у вас есть 100 ключевых слов, после просмотра 50 из них вам нужно запомнить, какие 50, и есть K (100,50) возможных комбинаций (иначе). 100891344545564193334812497256). Вот откуда берется факториал (K (100,50) равно 100! / (50! * 50!)). Ваше регулярное выражение должно быть в состоянии различать guish столько состояний, потому что для любых двух существует суффикс, который будет разрешен одним и отклонен другим.

1 голос
/ 22 апреля 2020

Однако это приводит к факториальному количеству регулярных выражений - 3! в приведенном выше примере k1 (k2)? (k3) ?, k1 (k3)? (k2) ?, k2 (k1)? (k3) ?, k2 (k3)? (k1) ?, k3 (k1)? ( k2) ?, k3 (k2)? (k1)? при последовательном запуске на одной и той же строке вы получите все вышеперечисленные совпадения.

Это правда.

Как это можно сделать более эффективным?

Используйте для выполнения работы надлежащий язык программирования / скрипт , Там вы можете использовать циклы и генерировать необходимые комбинации «легко», без хлопот регулярных выражений.


Примечание: регулярные выражения созданы не как универсальный инструмент, и определенно не для сложных, алгоритмы c задач.

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