Reputation:
I need to find if a file name contains some special characters I don't want.
I'm using this code actually:
$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.");
}
But I have an error saying:
Warning: preg_match_all(): Compilation failed: nothing to repeat at offset 38 in /home/public_html/upload.php on line 138
Which is:
$matchFound = preg_match_all("#\b(" . implode("|", $badChars) . ")\b#i", $file, $matches);
Any help or clue?
Upvotes: 0
Views: 2733
Reputation: 89574
it is because ?
*
+
are quantifiers. Since they are not escaped you obtain this error: |?
there is obviously nothing to repeat.
For your task you don't need to use an alternation, a character class should suffice:
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);
}
or perhaps this pattern: ~[^[:alnum:]]~
Upvotes: 1
Reputation: 59709
It's because your characters have *
in it, which tries to repeat the previous character, which in your case ends up being |
, which is invalid. Your regex turns into:
..... |/|*|-| .....
Map preg_quote()
to your character array before your loop and you'll be fine:
$badChars = array_map( 'preg_quote', $badChars);
Just make sure that since you're not specifying your delimiter #
in the call to preg_quote()
, you'll have to manually escape it in your $badChars
array.
Upvotes: 1