Почему этот негативный взгляд не работает? - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть это регулярное выражение, которое должно помочь мне найти и заменить устаревшие запросы mysql. По какой-то причине, хотя я заменяю один запрос, он перехватывает ту же область и просто расширяет ее до конца следующего устаревшего запроса. Я пытаюсь решить эту проблему, не позволяя ему выбрать конкретное ключевое слово в строке замены (stmt), но игнорирует это ограничение по какой-то причине.

\(?mis)\$(?<sql>[a-z0-9]*) = (?<query>"select.*?\;)(?:(?!stmt).*?)\$(?<res>[a-z0-9]*?) = mysql_query.*?\;(?<txt>.*?)while\s?\(\$(?<row>[a-z0-9]*?) = mysql.*?\{\ 1

Вот Regex101, который я использую для отладки.

(?:(?!stmt).*?) - вопрос, о котором идет речь. Я хочу, чтобы он разрешал произвольное количество текста между именованными группами захвата до и после. 2 *? уже должен заставить его найти наименьший раздел. Как вы можете видеть ниже, есть вполне приемлемое совпадение, начинающееся со строки 14 ($sql = "SELECT admin from user where id=" . $userID;), но оно настаивает на том, чтобы начинать все сначала сверху со старого и уже замененного совпадения.

Почему мой отрицательный взгляд не работает так, как я думаю, он должен работать? 3


enter image description here* * 1030


1. Я использую (?mis), потому что PHPStorm плохо играет с обычными флагами.
2. Чтобы предотвратить случайный код и неправильное форматирование, мешающие шаблону
3. Если это проблема XY, и я должен заставить правильное соответствие другим способом, я приветствую это как ответ вместо этого.

1 Ответ

1 голос
/ 26 апреля 2019

Отрицательный взгляд не совпадает, потому что он не совпадает. Он запрещает совпадение, когда за точкой с запятой в конце <query> сразу же следует «stmt», чего нет в вашем коде: за ним следуют символ новой строки, пробел, знак доллара, , затем"STMT".

Вы можете исправить эту часть, расширив отрицательный прогноз до (?!\s*\$stmt), но тогда становится очевидной вторая проблема: это просто расширяет совпадение <query> до следующей точки с запятой, за которой не следует на $stmt. Вы исправляете это, затягивая совпадение в <query>, чтобы жадно совпадать на точках с запятой, а не на жадности с чем-либо. То есть (?<query>"select.*?\;) становится (?<query>"select[^;]*\;). Это создает тупик для совпадения в первой точке с запятой.

Это не будет совпадать, если у вас есть какие-либо точки с запятой внутри SQL, но эй.

Это дает желаемый результат?

...