Негативный просмотр, похоже, не работает должным образом

Предположим, PHP-код

/**
 * @since             1.0.0 <--- this shouldn't be matched
 * @package           blah blah blah
 * Version:           1.0.0 <--- this should be matched
 */

/**
 * Fired during plugin activation.
 *
 * This class defines all code necessary to run during the plugin's activation.
 *
 * @since      1.0.0 <--- this shouldn't be matched
 * @package    blah blah
 * @subpackage blah blah
 * @author     blah blah
 */

define( 'PLUGIN_VERSION', '1.0.0' ); // <--- this should be matched

Я хочу сопоставить вхождения 1.0.0, которые не идут после строки @since, поэтому я хочу сопоставить только второе и третье.

Это регулярное выражение должно работать в VS.Code, и я искал этот шаблон (?<!since)(?:\s*)1\.0\.0, который, похоже, не работает. Что мне не хватает?

https://regex101.com/r/BGtDx6/1

🤔 А знаете ли вы, что...
С PHP можно создавать красивые и функциональные графики с помощью библиотеки GD.


2
50
2

Ответы:

Поскольку количество пробелов неизвестно, один из способов сделать это — отрицать since:

^(?im)\s*\*\s*(?!@since)[a-z]+\s*:\s*1\.0\.0

а затем, используя группу захвата, можно сопоставить 1.0.0:

^(?im)\s*\*\s*(?!@since)[a-z]+\s*:\s*(1\.0\.0)
  • ^: означает начало строки.
  • (?im): означает нечувствительные и многострочные флаги.
  • \s*: означает ноль или более пробелов.
  • \*: буквально *
  • (?!@since): исключает since.
  • [a-z]+: один или несколько символов от A до Z (также можно добавить другие символы)
  • (1\.0\.0): группа захвата, включающая 1.0.0 и к которой можно обращаться как $1

Для использования в среде VS Code следует удалить встроенный флаг:

(?!@since)[\w\s]+:\s*(1\.0\.0)|^\s*\w+\s*\(\s*['"]\s*[^'"]*['"]\s*,\s*['"]\s*([^'"]*)['"]\s*\)\s*;

Кажется, вы пытаетесь выполнить операцию поиска-замены. В этом случае:

  • просто сопоставьте * @since 1.0.0 с помощью простого регулярного выражения (@since\s+(1\.0\.0)) и замените его уникальной строкой, например A0P8x&2%.
  • Затем просто найдите 1.0.0 и внесите изменения.
  • Наконец, замените A0P8x&2% на * @since 1.0.0.

Решено

Вы можете добавить еще один просмотр назад, чтобы оглядываться назад только там, где раньше не было пробелов:

(?<!\s)(?<!since)\s*1\.0\.0

Посмотрите эту демонстрацию на сайте regex101

Это предотвратит успех последнего просмотра назад там, где ему предшествует пробел.
При необходимости вы можете захватить пробелы и повторно вставить в строку замены вот так.


Интересные вопросы для изучения

Как получить определенные ключ/значения из вторичного массива для поддержки моего процесса array_filter(Laravel 11) errno: 150 «Ограничение внешнего ключа сформировано неправильноЗапустить очередь Laravel из приложения PythonСписок заказов не отображается должным образом в laravel apiПереписать кавычки в элементы <q> в WordPressОбъединить многострочные строки в фрейме данных pandas на основе шаблона регулярного выраженияРегулярное выражение для текста, разделенного запятыми, с необязательными двойными кавычками, которые могут содержать кавычки, экранированные обратной косой чертойПочему эта замена регулярного выражения с использованием захвата зависает в этом быстром коде?Токенизация XSLT с помощью регулярного выражения для токенизации только в том случае, если за точкой с запятой не следует пробел и числоRegex соответствует определенным шаблонам URL-адресов