Игнорировать строку, содержащую

Использование регулярного выражения PCRE2 для замены PHP-скрипта

Цель этого регулярного выражения — добавить ?? '' к вызову функции strlen (PHP), если она в данный момент не существует. Я планирую использовать группу захвата регулярных выражений для выполнения замен в VS Code с помощью strlen($1 ?? ''). Следующая текстовая строка используется для проверки регулярного выражения:

$strStatement2 = substr($strStatement3, strlen('my capture group'));  # want a match on `strlen('my capture group')` with a capturing group of `'my capture group'`

$strStatement2 = substr($strStatement3, 0, strlen('my capture group') - 1);  # want a match on `strlen('my capture group')` with a capturing group of `'my capture group'`

$strStatement2 = strlen($doNotWantAMatch ?? '') != strlen('my capture group');  # do not want a match on the first instance of `strlen` since it contains ` ?? ''` but I do want to match the second instance of `strlen('my capture group')`

Если я попробую регулярное выражение strlen\((?:(?! ?? '')(.))+\) (при условии использования /[regex here]/gm), я получу совпадения со следующим (после удаления комментариев в конце строк):

$strStatement2 = substr($strStatement3, strlen('my capture group'));

$strStatement2 = substr($strStatement3, 0, strlen('my capture group') - 1);

$strStatement2 = strlen($doNotWantAMatch ?? '') != strlen('my capture group');

Это хорошо, потому что strlen($doNotWantAMatch ?? '') как минимум игнорируется, но остальные совпадения неверны.

Основное регулярное выражение, которое мне нужно, — это strlen\((.+?)\), которое формирует группу захвата для аргумента внутри функции strlen, которую я пытаюсь заменить. Регулярное выражение strlen\((?:(?! ?? '')(.+?))\) приближает меня, поскольку оно дает группы захвата, за исключением того, что оно не может игнорировать группу совпадений и захвата для strlen($strStatement3 ?? ''). Если я использую strlen\(.*?(?: \?\? '')\)|strlen\((.+?)\), я получаю нужные группы захвата (в том смысле, что не создается группа захвата для strlen($strStatement3 ?? '')), но мне не нужно совпадение с strlen($doNotWantAMatch ?? '') (что вызвано оператором «или» |, но к этому моменту я хватаюсь за соломинку).

Я чувствую, что близок к решению, но не могу пересечь финишную черту в решении этой проблемы. Используем https://regex101.com/r/HRWt8Q/1 для тестирования.

Обновлять

@anubhava предоставил ответ, и в итоге я использовал strlen\(((?:[^)](?!\?\? ''))+)\) в VSCode для поиска экземпляров strlen() в PHP-скриптах, которым по умолчанию требовалась пустая строка для PHPv8.1. если передается нулевое значение (поскольку передача пустой строки в strlen() теперь не рекомендуется). Это помогло мне обновить мой старый PHP-код до PHPv8.1, где многим функциям необходимо передавать в них что-то кроме null.

Вам определенно нужно избегать ?, который должен соответствовать буквально.

Barmar 12.06.2024 19:10

Я не уверен, что это можно сделать с помощью одного регулярного выражения. Они не умеют фильтровать что-либо внутри контекста. Если вы делаете это с помощью языка программирования, вы сначала сопоставляете все вызовы strlen(), а затем проверяете, есть ли уже в содержимом ?? ''

Barmar 12.06.2024 19:12

Примечание. Это регулярное выражение не учитывает что-то вроде strlen(trim($this->txtNoteLog->Text)), когда в качестве аргумента функции strlen имеется вызов другой функции. В таких случаях замена будет неправильной strlen(trim($this->txtNoteLog->Text ?? '')).

w. Patrick Gale 03.07.2024 22:35

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

Barmar 03.07.2024 23:06
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
4
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать это регулярное выражение для захвата текста между strlen( и ), который не должен содержать ??:

strlen\(((?:[^)](?!\?\? ''))+)\)

Демо RegEx

Подробности регулярного выражения:

  • strlen\(: Матч strlen(
  • (: Запустить группу захвата.
    • (?:: Запустить группу без захвата.
      • [^)]: Сопоставьте любой символ, кроме ).
      • (?!\?\? ''): Отрицательный прогноз для неудачного совпадения, если следующий символ ?? ''
    • )+: Завершить группу без захвата. Соответствует 1+ из этой группы без захвата
  • ): Завершить группу захвата
  • \): Закрытие матча )

Круто, спасибо @anubhava. Это очень полезно. В итоге я использовал strlen\(((?:[^)](?!\?\? ''))+)\), так как мне нужно было искать экземпляры ` ?? ''` игнорировать. При использовании в VS Code (VSC), если я пытался выйти из пробела и одинарных кавычек в ` ''`, VSC выдал ошибку invalid regular expression (поэтому в этом шаблоне регулярного выражения они не заключены в кавычки). Еще раз спасибо :)

w. Patrick Gale 12.06.2024 20:12

Ой, я пропустил '', сейчас обновил свой ответ.

anubhava 12.06.2024 20:26

Можешь попробовать:

\bstrlen\b\(\s*[\w$'"\s]+\s*\)
  • Один из способов — просто добавить те символы, которые вас интересуют, в [\w$'"\s] и исключить те, которые вам не нужны.

  • Другой способ — сделать выкройку более свободной:
\bstrlen\b\(\s*([^?\r\n]+?)?\s*\)
  • [^?\r\n] исключает только ? и \r\n.

Код:

import re

s = """substr($strStatement3, strlen('if'))
substr($strStatement3, strlen('if'))
substr($strStatement3, 0, strlen($strStatement) - 1)
substr($strStatement3, strlen('my capture group'));  # want a match on `strlen('my capture group')` with a capturing group of `'my capture group'
substr($strStatement3, 0, strlen('my capture group') - 1);  # want a match on `strlen('my capture group')` with a capturing group of `'my capture group'
substr($strStatement3, `strlen('my capture group'))`
substr($strStatement3, 0, `strlen('my capture group') - 1)`
"""

p = r'\bstrlen\b\(\s*([^?\r\n]+?)?\s*\)'
f = re.findall(p, s)

for found in f:
    print(found)

Принты

'if'
'if'
$strStatement
'my capture group'
'my capture group'
'my capture group'
'my capture group'
'my capture group'
'my capture group'

К сожалению, это не включает группы захвата (которые необходимы для поиска и замены в VS Code). В любом случае, я ценю альтернативу, которая может быть полезна кому-то еще. Ваше здоровье.

w. Patrick Gale 12.06.2024 20:21

@w.PatrickGale Просто добавьте это.

user24714692 12.06.2024 20:22

Ух ты. Я понятия не имею, как читать \bstrlen\b\(\s*([^?\r\n]+?)?\s*\), но, похоже, это работает. Спасибо @user24714692.

w. Patrick Gale 12.06.2024 22:49

Другие вопросы по теме

Похожие вопросы

RegEx для проверки координат в различных форматах
RegEx для исключения двух строк без отрицательного просмотра
Регулярное выражение для соответствия необязательному префиксу, заканчивающемуся определенным символом
Шаблон регулярного выражения, позволяющий использовать буквенно-цифровые и квадратные скобки с текстом внутри него
Заменить первое вхождение серии из одного или нескольких пробелов в строке
Удалить части подстроки с помощью нескольких условий
Как мне получить номер телефона и расширение этого номера телефона, используя регулярное выражение
Java String.split(delim) оставляет пустую строку в начале, если исходная строка начинается с разделителя
Регулярное выражение для поиска имен файлов с определенными параметрами, но не с другими
Как получить текст из текущей строки в указанной позиции курсора до и после указанных граничных символов?