PHP Regex - 匹配一个字符组,当该字符组中的一个不在字符串中时

时间:2016-06-20 15:11:00

标签: php regex regex-negation regex-lookarounds

我觉得我一直撞到砖墙上。

我有一个看起来像这样的字符串:

$record['filenameGood'] = '49161_Comma_Dataphoria-Clickwork7Export{DATE:dmY}';

我想阻止包含任何受限字符的文件名。

但是......我正在使用占位符作为当前日期,看起来像{DATE:Y-m-d},其中Y-m-d将被插入到php的{​​{1}}函数中。 这部分我很好,它只是确保字符串的其余部分不包含受限字符。

我正在测试的脚本如下所示:

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:}

我希望我已经足够清楚地解释了这一点!

1 个答案:

答案 0 :(得分:2)

您可以在字符类之后使用负面的lookbehind

$patternTwo = '#["*:%$/\\\\\'?](?<!{DATE:)#';
                               ^^^^^^^^^^^

请参阅IDEONE demo

此处,首先匹配字符类中的一个字符,但负面的lookbehind将检查:是否前面没有{DATE。如果是,则匹配将失败。