错误:在PHP中的preg_match_all期间,无法在偏移错误处重复

时间:2015-02-11 14:04:28

标签: php regex

我需要查找文件名是否包含一些我不想要的特殊字符。

我实际上正在使用此代码:

$files = array("logo.png", "légo.png");
$badChars = array(" ", "é", "É", "è", "È", "à", "À", "ç", "Ç", "¨", "^", "=", "/", "*", "-", "+", "'", "<", ">", ":", ";", ",", "`", "~", "/", "", "|", "!", "@", "#", "$", "%", "?", "&", "(", ")", "¬", "{", "}", "[", "]", "ù", "Ù", '"', "«", "»");
$matches = array();

foreach($files as $file) {
    $matchFound = preg_match_all("#\b(" . implode("|", $badChars) . ")\b#i", $file, $matches);
}
if ($matchFound) {
    $words = array_unique($matches[0]);
    foreach($words as $word) {
        $results[] = array('Error' => "Forbided chars found : ". $word);
    }
}
else {
    $results[] = array('Success' => "OK.");
}

但我有一个错误说:

Warning: preg_match_all(): Compilation failed: nothing to repeat at offset 38 in /home/public_html/upload.php on line 138

这是:

$matchFound = preg_match_all("#\b(" . implode("|", $badChars) . ")\b#i", $file, $matches);

任何帮助或线索?

2 个答案:

答案 0 :(得分:1)

这是因为你的角色中有*,它会尝试重复前一个角色,在你的情况下最终为|,这是无效的。你的正则表达式转变为:

..... |/|*|-| .....

在你的循环之前将preg_quote()映射到你的角色数组,你会没事的:

$badChars = array_map( 'preg_quote', $badChars);

请确保由于您未在#的调用中指定分隔符preg_quote(),因此您必须在$badChars数组中手动​​转义分隔符{{1}}

答案 1 :(得分:1)

这是因为? * +是量词。由于它们未被转义,因此您会收到此错误:|?显然没有什么可重复的。

对于您的任务,您不需要使用替换,字符类应该足够:

if (preg_match_all('~[] éèàç¨^=/*-+\'<>:;,`\~/|!@#$%?&()¬{}[ù"«»]~ui', $file, $m)) {
    $m = array_unique($m[0]);
    $m = array_map(function ($i) use ($file) { return array('Error' => 'Forbidden character found : ' . $i . ' in ' . $file); }, $m);
    $results = array_merge($results, $m);
}

或者这种模式:~[^[:alnum:]]~