我真的为了解决这个问题而奋斗了一夜......但是:(
在表单中,用户输入一个单词,我需要检查他的输入是否包含预设的字符表中的字符:
abggwdḍefkkwhḤƐxqijlmnurṚɣsṢctṬwyzẒ
到目前为止,我使用的是在php.net中找到的代码:
$temp_s = mb_convert_encoding($post['word'],'UTF-16','UTF-8');
$temp_a = str_split($temp_s,4);
$temp_a_len = count($temp_a);
for($i=0; $i<$temp_a_len; $i++){
$temp_a[$i] = mb_convert_encoding($temp_a[$i],'UTF-8','UTF-16');
$pos = stripos( mb_strtolower($allowed), mb_strtolower($temp_a[$i]) );
if($pos === false){
echo '- '. mb_strtolower($temp_a[$i]) .' -is not allowed in '.mb_strtolower($allowed);
return false;
}
}
我做错了什么?因为如果我提交它输出的字符ḍ
:
- ḍ -is not allowed in abggwdḌefkkwhḤƐxqijlmnurṚɣsṢctṬwyzẒ
UPDATE 另一件事是如何允许$ allowed字符列表的大写或小写版本?
答案 0 :(得分:2)
简单如下:
$unwanted = 'abggwdḍefkkwhḤƐxqijlmnurṚɣsṢctṬwyzẒ';
$badText = 'Foo baṚ Baz';
$goodText = '345235';
if (preg_match_all("/[$unwanted]/u", $badText, $matches)) {
echo "Bad text is bad, invalid characters: " . join(', ', $matches[0]) . PHP_EOL;
}
if (preg_match_all("/[$unwanted]/u", $goodText, $matches)) {
echo "Good text is bad, invalid characters: " . join(', ', $matches[0]) . PHP_EOL;
}
请注意,您的源代码需要以UTF-8保存,输入也必须是UTF-8。
我真的质疑使用UTF-8黑名单,因为有数十万个代码点。将这些部分列入黑名单似乎是一场毫无用处的艰苦战斗。如果你不允许“Ṛ”,为什么你会接受“Ŗ”或任何其他类似“R”字符的变体。抓住它们都是徒劳的。考虑实现白名单。 (也就是说,如果我理解你要做什么的话。这不是很清楚。)
请注意,字符可能是decomposed,这意味着它们与您的表达式不匹配。例如,ü
可以是字符ü
(U + 00FC)或ü
(U + 0075 U + 0308,即u
后跟合并{{1} }})。您应该将字符标准化为NFC(Canonical Decomposition后跟Canonical Composition),这意味着任何形式的¨
都将标准化为U + 00FC。在PHP中,您可以使用:
ü
默认情况下,默认情况下并未安装Normalizer
class。
答案 1 :(得分:1)
我的日食没有问题
$allowed = 'ḍabggwdefkkwhḤƐxqijlmnurṚɣsṢctṬwyzẒ';
$temp_s = mb_convert_encoding('ḍ','UTF-16','UTF-8');
$temp_a = str_split($temp_s,4);
$temp_a_len = count($temp_a);
for($i=0; $i<$temp_a_len; $i++){
$temp_a[$i] = mb_convert_encoding($temp_a[$i],'UTF-8','UTF-16');
$pos = stripos( mb_strtolower($allowed), mb_strtolower($temp_a[$i]) );
if($pos === false){
echo '- '. mb_strtolower($temp_a[$i]) .' -is not allowed in '.mb_strtolower($allowed);
}
}
答案 2 :(得分:1)
您发布的代码实际上似乎没有给我任何错误,但这是一个较短的版本。也许看看这是否符合你的要求。
$input = 'ḍwhat';
$allowed = mb_strtolower('ḍabggwdefkkwhḤƐxqijlmnurṚɣsṢctṬwyzẒ');
foreach (preg_split('//u', $input) as $c) {
if (mb_strlen($c) !== 0 && mb_strpos($allowed, mb_strtolower($c)) === FALSE) {
echo '-' . $c . '- is not allowded in ' . $allowed;
return false;
}
}
我唯一要说的是使用str_split($temp_s,2);
来尝试原始代码,因为4并不总是有效,而更多的UTF-16东西将是2个字节。两者都可能会破裂。