Regex для получения строки между речевыми метками в любом месте строки - PullRequest
1 голос
/ 04 июня 2019

Я работаю над проектом, в котором я пытаюсь извлечь строку между двумя речевыми метками в любом месте строки.Это почти работает, за исключением одной вещи.

Допустим, у меня есть строка

"04\/06\/2019 17:56:45:\tTook 0 seconds to read lines for log 'Log Agent

Идея, что я сделаю два совпадения с регулярным выражением, одно для строки, в которой нет восклицательного знаканапример, я сделаю поиск по регулярному выражению, чтобы найти соответствие "Took 0 seconds", а другой - что-то вроде !"Took 0 seconds"

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

$regex = '/[^.!](["\'])(?:(?=(\\\\?))\2.)*?\1/m';
            $matches = null;
            preg_match_all($regex, $this->searchString, $matches, PREG_SET_ORDER, 0);

Но приведенное выше регулярное выражение соответствует строке, только если перед строкой есть что-то, но ничего не находит

Например, если строка поиска "Took 0 seconds", она не найдена

если его some other content "Took 0 seconds", то он правильно находит строку Took 0 seconds в совпадении с регулярным выражением.

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

ОБНОВЛЕНИЕ

Попробуйте уточнить, что я делаю.Я создаю анализатор поиска, чтобы найти определенные строки в базе данных.

Поиск в базе данных будет искать отдельные ключевые слова (не относящиеся к этому вопросу, которые легко сделать) и искать конкретную строку в базе данных.Так что если моя строка поиска "took 0 seconds", то база данных будет возвращать любые строки, содержащие запись took 0 seconds.Если строка поиска будет !"took 0 seconds", тогда я смогу проверить, не содержит ли база данных Took 0 seconds.

Если бы строка поиска была keyword1 keyword2 "took 0 seconds" keyword 3, то регулярное выражение вернуло бы "took 0 seconds"

Ниже приведена ссылка regex101 , которая дает несколько примеров и в чем проблема, выВы заметите, что первый, где он просто «занял 0 секунд», сам по себе не подходит.

1 Ответ

3 голосов
/ 04 июня 2019

Как отметили @ Toto в комментариях, вы можете использовать отрицательный вид сзади вместо сопоставления символов в классе символов.

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

(?<![.!])(["'])(?:(?!\1).)*\1
  • (?<![.!])
  • (["']) Захват в группе 1 либо ", либо '
  • (?:(?!\1).)* Цикл 0+ раз соответствует любому символу, в то время как то, что справа не является группой 1
  • \1 Соответствует обратная ссылка на группу 1

Regex demo

Обратите внимание, что из-за квантификатора * он также будет соответствовать ""

Другим способом получения этих совпадений может быть использование не жадного совпадения .*?, за которым следует группа 1 \1

(?<![.!])(["\']).*?\1

Regex demo

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