Я чувствую, что ударился головой о кирпичную стену.
У меня есть строка, которая выглядит так:
$record['filenameGood'] = '49161_Comma_Dataphoria-Clickwork7Export{DATE:dmY}';
И я хочу заблокировать имена файлов, которые содержат любые запрещенные символы.
Однако … Я использую заполнитель для текущей даты, которая выглядит как {DATE:Y-m-d}
где Y-m-d
будет вставлен в php
s date
функция.
Эта часть меня устраивает, она просто гарантирует, что остальная часть строки не содержит ограниченный символ.
Скрипт, с которым я тестирую, выглядит так:
// Matches one of " * : % $ / \ ' ?
$patternOne = '#["*:%$/\\\'?]#';
// Desired: matches one of " * : % $ / \ ' ?, but ALLOWS {DATE:.*?}
$patternTwo = '#["*:%$/\\\'?]#';
$record = [];
$record['filenameGood'] = '49161_Comma_Dataphoria-Clickwork7Export{DATE:dmY}';
$record['filenameBad'] = '49161_Comma_Dataphoria-Clickwork7:Export{DATE:dmY}';
var_dump(preg_match($patternTwo, $record['filenameGood']));
var_dump(preg_match($patternTwo, $record['filenameBad']));
Токовый выход:
int(1)
int(1)
В то время как мой желаемый результат:
int(0) // Good string, contains : within {DATE:}
int(1) // Bad string, contains a : NOT within {DATE:}
Мне также нужна строка, подобная следующей, чтобы получить соответствие:
'49161_Comma_Dataphoria-Clickwork7Export{DATE:d:m:Y}'
Надеюсь, я объяснил это достаточно хорошо, чтобы вы поняли!
Вы можете использовать отрицательный взгляд сзади после класс персонажа:
$patternTwo = '#["*:%$/\\\\\'?](?<!{DATE:)#';
^^^^^^^^^^^
Увидеть IDEONE демо.
Здесь, один из символов в классе символов сначала сопоставляется, но затем отрицательный взгляд за спиной проверит, :
не предшествует {DATE
, Если это так, матч будет неудачным.
Других решений пока нет …