Цель этого регулярного выражения — добавить ?? '' к вызову функции 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.
Я не уверен, что это можно сделать с помощью одного регулярного выражения. Они не умеют фильтровать что-либо внутри контекста. Если вы делаете это с помощью языка программирования, вы сначала сопоставляете все вызовы strlen(), а затем проверяете, есть ли уже в содержимом ?? ''
Примечание. Это регулярное выражение не учитывает что-то вроде strlen(trim($this->txtNoteLog->Text)), когда в качестве аргумента функции strlen имеется вызов другой функции. В таких случаях замена будет неправильной strlen(trim($this->txtNoteLog->Text ?? '')).
Не следует обновлять вопрос своим решением. Если это то же самое, что ответ Анубхавы, достаточно принять ответ. Если вы изменили их ответ, вам следует опубликовать свое решение как новый ответ и принять его.





Вы можете использовать это регулярное выражение для захвата текста между strlen( и ), который не должен содержать ??:
strlen\(((?:[^)](?!\?\? ''))+)\)
Подробности регулярного выражения:
strlen\(: Матч strlen((: Запустить группу захвата.
(?:: Запустить группу без захвата.
[^)]: Сопоставьте любой символ, кроме ).(?!\?\? ''): Отрицательный прогноз для неудачного совпадения, если следующий символ ?? '')+: Завершить группу без захвата. Соответствует 1+ из этой группы без захвата): Завершить группу захвата\): Закрытие матча )Круто, спасибо @anubhava. Это очень полезно. В итоге я использовал strlen\(((?:[^)](?!\?\? ''))+)\), так как мне нужно было искать экземпляры ` ?? ''` игнорировать. При использовании в VS Code (VSC), если я пытался выйти из пробела и одинарных кавычек в ` ''`, VSC выдал ошибку invalid regular expression (поэтому в этом шаблоне регулярного выражения они не заключены в кавычки). Еще раз спасибо :)
Ой, я пропустил '', сейчас обновил свой ответ.
Можешь попробовать:
\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.PatrickGale Просто добавьте это.
Ух ты. Я понятия не имею, как читать \bstrlen\b\(\s*([^?\r\n]+?)?\s*\), но, похоже, это работает. Спасибо @user24714692.
Вам определенно нужно избегать
?, который должен соответствовать буквально.