PHP의 UTF-8 문자열에서 4바이트 문자를 대체/제거하는 방법은 무엇입니까?
MySQL은 기본 UTF-8 문자 집합에서 3바이트 이상의 문자를 지원하지 않는 것 같습니다.
그렇다면 PHP에서 문자열에서 4바이트 이상의 문자를 모두 제거하고 다른 문자와 같은 문자로 대체하려면 어떻게 해야 합니까?
참고: 유니코드 공격(대부분 XSS)을 방지하기 위해 단순히 제거하지 말고 대체 문자 U+FFFD로 대체해야 합니다.
http://unicode.org/reports/tr36/ #비문자 삭제_of_비문자
preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $value);
4바이트 UTF-8 시퀀스는 항상 바이트로 시작하므로0xF0-0xF7
다음이 작동해야 합니다.
$str = preg_replace('/[\xF0-\xF7].../s', '', $str);
또는 다음을 사용할 수 있습니다.preg_replace
UTF-8 모드에서는 속도가 느려집니다.
$str = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $str);
이것은 4바이트 UTF-8 시퀀스가 다음으로 시작하는 보조 유니코드 평면의 코드 포인트에 사용되기 때문에 작동합니다.0x10000
.
다음은 예입니다.
<?php
mb_internal_encoding("UTF-8");
//utf8 string, 13 bytes, 9 utf8 chars, 7 ASCII, 1 in latin1, 1 outside the BMP
$str = "qué \xF0\x9D\x92\xB3 tal";
$array = mbStringToArray($str);
print "str: [$str] strlen:" . strlen($str) . " chars:" . count($array) . "\n";
$str1 = "";
foreach($array as $c) {
// print "$c : " . strlen($c) ."\n";
$str1 .= strlen($c)<=3? $c : '?';
}
print "[$str1]\n";
function mbStringToArray ($str) {
if (empty($str)) return false;
$len = mb_strlen($str);
$array = array();
for ($i = 0; $i < $len; $i++) {
$array[] = mb_substr($str, $i, 1);
}
return $array;
}
또는 좀 더 작고 효율적입니다.
<?php ///
mb_internal_encoding("UTF-8");
//utf8 string, 13 bytes, 9 utf8 chars, 7 ASCII, 1 in latin1, 1 outside the BMP
$str = "qué \xF0\x9D\x92\xB3 tal";
$str1 = trimOutsideBMP($str);
print "original: [$str]\n";
print "trimmed: [$str1]\n";
// Replaces non-BMP characters in the UTF-8 string by a '?' character
// Assumes UTF-8 default encoding ( if not sure, call first mb_internal_encoding("UTF-8"); )
function trimOutsideBMP($str) {
if (empty($str)) return $str;
$len = mb_strlen($str);
$str1 = '';
for ($i = 0; $i < $len; $i++) {
$c = mb_substr($str, $i, 1);
$str1 .= strlen($c) <= 3 ? $c : '?';
}
return $str1;
}
나만의 문제를 해결하려고 할 때 이 질문을 발견했습니다(페이스북은 특정 이모티콘을 4바이트 문자로 뱉습니다, Amazon Mechanical Turk는 4바이트 문자를 허용하지 않습니다).
나는 이것을 사용하게 되었고, mbstring 확장이 필요하지 않습니다.
function remove_4_byte($string) {
$char_array = preg_split('/(?<!^)(?!$)/u', $string );
for($x=0;$x<sizeof($char_array);$x++) {
if(strlen($char_array[$x])>3) {
$char_array[$x] = "";
}
}
return implode($char_array, "");
}
아래 함수는 3 및 4바이트 문자를 utf8 문자열에서 '#'로 변경합니다.
function remove3and4bytesCharFromUtf8Str($str) {
return preg_replace('/([\xF0-\xF7]...)|([\xE0-\xEF]..)/s', '#', $str);
}
다음은 4바이트 문자를 필터링하기 위한 구현입니다.
$string = preg_replace_callback(
'/./u',
function (array $match) {
return strlen($match[0]) >= 4 ? null : $match[0];
},
$string
);
당신은 그것을 수정하고 교체할 수 있습니다.null
(char를 제거함) 일부 대체 문자열을 사용합니다.교체할 수도 있습니다.>= 4
다른 바이트 길이 검사와 함께.
또 다른 필터 구현, 더 복잡합니다.
ASCII 문자로 변환을 시도하고, 그렇지 않으면 유니코드 대체 문자를 사용하여 XSS를 방지합니다.<a href='java\uFEFFscript:alert("XSS")'>
$tr = preg_replace_callback('/([\x{10000}-\x{10FFFF}])/u', function($m){
$c = iconv('ISO-8859-2', 'UTF-8',iconv('utf-8','ISO-8859-2//TRANSLIT//IGNORE', $m[1]));
if($c == '')
return '�';
return $c;
}, $s);
언급URL : https://stackoverflow.com/questions/8491431/how-to-replace-remove-4-byte-characters-from-a-utf-8-string-in-php
'programing' 카테고리의 다른 글
MySQL 데이터베이스에 아랍어로 데이터 저장 (0) | 2023.07.29 |
---|---|
함수에 매개 변수로 전달하지 않고 Spring에서 현재 사용자 로케일을 가져오는 방법은 무엇입니까? (0) | 2023.07.29 |
리스트에서 특이치를 기각하기 위한 numpy가 내장되어 있습니까? (0) | 2023.07.29 |
Android에서 이미지 보기의 투명 배경 설정 (0) | 2023.07.29 |
수직 격자선을 matplotlib의 선 그림에 표시 (0) | 2023.07.29 |