문자열에서 utf8이 아닌 문자 제거
문자열에서 utf8 이외의 문자를 삭제하는 데 문제가 있어 올바르게 표시되지 않습니다.문자는 다음과 같습니다. 0x97 0x61 0x6C 0x6F(16진수 표시)
그것들을 제거하는 가장 좋은 방법은 무엇입니까?정규 표현 같은 거?
「」를 utf8_encode()
UTF8은 UTF8로, UTF8은 UTF8로, UTF8은 UTF8로 되어 있다.
저는 이 모든 문제를 해결할 수 있는 기능을 만들었습니다.'어느덧 하다'라고 해요.Encoding::toUTF8()
.
이치노Latin1(ISO8859-1), Windows-1252의 UTF8을 사용합니다. Encoding::toUTF8()
UTF8을 사용하다
한 서비스에서는 모든 데이터가 엉망이 되어 같은 문자열로 인코딩되어 있기 때문에 그렇게 했습니다.
사용방법:
require_once('Encoding.php');
use \ForceUTF8\Encoding; // It's namespaced now.
$utf8_string = Encoding::toUTF8($mixed_string);
$latin1_string = Encoding::toLatin1($mixed_string);
UTF8에 여러 번 인코딩된 것처럼 보이는 모든 UTF8 문자열을 수정하는 인코딩::fixUTF8() 함수를 추가했습니다.
사용방법:
require_once('Encoding.php');
use \ForceUTF8\Encoding; // It's namespaced now.
$utf8_string = Encoding::fixUTF8($garbled_utf8_string);
예:
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
출력:
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
다운로드:
https://github.com/neitanod/forceutf8
regex 접근법 사용:
$regex = <<<'END'
/
(
(?: [\x00-\x7F] # single-byte sequences 0xxxxxxx
| [\xC0-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
| [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences 1110xxxx 10xxxxxx * 2
| [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3
){1,100} # ...one or more times
)
| . # anything else
/x
END;
preg_replace($regex, '$1', $text);
UTF-8 시퀀스를 검색하여 그룹1로 캡처합니다.또한 UTF-8 시퀀스의 일부로 식별되지 않은 단일 바이트와 일치하지만 이러한 바이트는 캡처되지 않습니다.대체는 그룹 1에 포착된 것입니다.이것에 의해, 무효인 바이트가 모두 삭제됩니다.
비활성 바이트를 UTF-8 문자로 인코딩하여 문자열을 복구할 수 있습니다.하지만 오류가 무작위로 발생하면 이상한 기호가 남을 수 있습니다.
$regex = <<<'END'
/
(
(?: [\x00-\x7F] # single-byte sequences 0xxxxxxx
| [\xC0-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
| [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences 1110xxxx 10xxxxxx * 2
| [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3
){1,100} # ...one or more times
)
| ( [\x80-\xBF] ) # invalid byte in range 10000000 - 10111111
| ( [\xC0-\xFF] ) # invalid byte in range 11000000 - 11111111
/x
END;
function utf8replacer($captures) {
if ($captures[1] != "") {
// Valid byte sequence. Return unmodified.
return $captures[1];
}
elseif ($captures[2] != "") {
// Invalid byte of the form 10xxxxxx.
// Encode as 11000010 10xxxxxx.
return "\xC2".$captures[2];
}
else {
// Invalid byte of the form 11xxxxxx.
// Encode as 11000011 10xxxxxx.
return "\xC3".chr(ord($captures[3])-64);
}
}
preg_replace_callback($regex, "utf8replacer", $text);
편집:
!empty(x)
빈 값이 아닌 값과 일치합니다("0"
빈 것으로 간주됩니다).x != ""
다음과 같은 빈 값이 아닌 값과 일치합니다."0"
.x !== ""
를 제외한 모든 것과 일치합니다.""
.
x != ""
이 경우에 사용하는 것이 가장 좋을 것 같습니다.
나도 시합에 조금 속도를 냈다.각 문자를 개별적으로 대조하는 것이 아니라 유효한 UTF-8 문자의 시퀀스를 대조합니다.
mbstring 을 사용할 수 있습니다.
$text = mb_convert_encoding($text, 'UTF-8', 'UTF-8');
...잘못된 문자를 제거합니다.
참조: 비활성 UTF-8 문자를 물음표 mbstring.substitute_character로 대체하면 무시되는 것 같습니다.
는 ASCII 이외의를 모두 함수는 하지만 다음는 못합니다.ASCII는 ASCII를 사용하지 않습니다. 유용하지만 문제를 해결하지는 못합니다.
'CHANGE: 'CHANGE: 'CHANGE: 'CHANGE: 'CHANGE:
function remove_bs($Str) {
$StrArr = str_split($Str); $NewStr = '';
foreach ($StrArr as $Char) {
$CharNo = ord($Char);
if ($CharNo == 163) { $NewStr .= $Char; continue; } // keep £
if ($CharNo > 31 && $CharNo < 127) {
$NewStr .= $Char;
}
}
return $NewStr;
}
구조:
echo remove_bs('Hello õhowå åare youÆ?'); // Hello how are you?
$text = iconv("UTF-8", "UTF-8//IGNORE", $text);
이게 제가 쓰고 있는 거예요.꽤 효과가 있는 것 같네요.http://planetozh.com/blog/2005/01/remove-invalid-characters-in-utf-8/에서 가져온 정보
이것을 시험해 보세요.
$string = iconv("UTF-8","UTF-8//IGNORE",$string);
iconv 매뉴얼에 따르면 함수는 첫 번째 파라미터를 입력 문자 집합으로, 두 번째 파라미터를 출력 문자 집합으로, 세 번째 파라미터를 실제 입력 문자열로 사용합니다.
입력 문자 집합과 출력 문자 집합을 모두 UTF-8로 설정하고,//IGNORE
출력 문자 집합으로 플래그를 지정하면 함수는 출력 문자 집합으로 나타낼 수 없는 입력 문자열의 모든 문자를 드롭(스트립)합니다.이치노
텍스트에 utf8 이외의 문자가 포함될 수 있습니다.먼저 시도:
$nonutf8 = mb_convert_encoding($nonutf8 , 'UTF-8', 'UTF-8');
자세한 것은, http://php.net/manual/en/function.mb-convert-encoding.php[뉴스][2]를 참조해 주세요.
UConverter는 PHP 5.5부터 사용할 수 있습니다.intl 확장자를 사용하고 mbstring을 사용하지 않는 경우 UConverter를 선택하는 것이 좋습니다.
function replace_invalid_byte_sequence($str)
{
return UConverter::transcode($str, 'UTF-8', 'UTF-8');
}
function replace_invalid_byte_sequence2($str)
{
return (new UConverter('UTF-8', 'UTF-8'))->convert($str);
}
htmlspecialchars를 사용하여 PHP 5.4 이후 비활성 바이트 시퀀스를 제거할 수 있습니다.Htmlspecialchars는 큰 사이즈의 바이트와 정밀도를 처리하는 데 preg_match보다 우수합니다.정규 표현을 사용하면 잘못된 구현이 많이 나타납니다.
function replace_invalid_byte_sequence3($str)
{
return htmlspecialchars_decode(htmlspecialchars($str, ENT_SUBSTITUTE, 'UTF-8'));
}
안녕하세요 간단한 regex를 사용할 수 있습니다.
$text = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $text);
UTF-8 이외의 모든 문자를 문자열에서 잘라냅니다.
문자열에서 비활성 UTF-8 문자를 삭제하는 기능을 만들었습니다.XML 내보내기 파일을 생성하기 전에 27000개 제품에 대한 설명을 지우는 데 사용합니다.
public function stripInvalidXml($value) {
$ret = "";
$current;
if (empty($value)) {
return $ret;
}
$length = strlen($value);
for ($i=0; $i < $length; $i++) {
$current = ord($value{$i});
if (($current == 0x9) || ($current == 0xA) || ($current == 0xD) || (($current >= 0x20) && ($current <= 0xD7FF)) || (($current >= 0xE000) && ($current <= 0xFFFD)) || (($current >= 0x10000) && ($current <= 0x10FFFF))) {
$ret .= chr($current);
}
else {
$ret .= "";
}
}
return $ret;
}
과 2019년에 것을 합니다./u
UTF-8 regex
" " " 을 사용하는 mb_convert_encoding($value, 'UTF-8', 'UTF-8')
가 계속 됩니다.
이 방법은 다음과 같습니다.
- 를 UTF-8로 모두 합니다.
mb_convert_encoding
- 다음과 같이 인쇄할 수 없는 모든 문자 제거
\r
,\x00
NULL 바이트)및 제어 문자(NULL " " ) :preg_replace
방법:
function utf8_filter(string $value): string{
return preg_replace('/[^[:print:]\n]/u', '', mb_convert_encoding($value, 'UTF-8', 'UTF-8'));
}
[:print:]
와 ""를 합니다.\n
바꿈
ASCII를 사용하다~127이지만, ~127 입니다.\n
0 ~ 의 0 ~31 의 newline 에 을 ./[^[:print:]\n]/u
와 함께 수 .\x7F
(),),\x1B
).
function utf8_filter(string $value): string{
return preg_replace('/[^[:print:]\n]/u', '', mb_convert_encoding($value, 'UTF-8', 'UTF-8'));
}
$arr = [
'Danish chars' => 'Hello from Denmark with æøå',
'Non-printable chars' => "\x7FHello with invalid chars\r \x00"
];
foreach($arr as $k => $v){
echo "$k:\n---------\n";
$len = strlen($v);
echo "$v\n(".$len.")\n";
$strip = utf8_decode(utf8_filter(utf8_encode($v)));
$strip_len = strlen($strip);
echo $strip."\n(".$strip_len.")\n\n";
echo "Chars removed: ".($len - $strip_len)."\n\n\n";
}
https://www.tehplayground.com/q5sJ3FOddhv1atpR
$string = preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_COMPAT, 'UTF-8'));
따라서 첫 번째 UTF-8 옥텟은 높은 비트를 마커로 설정하고 그 다음 1~4비트를 추가 옥텟의 수를 나타냅니다.그 후 추가된 각 옥텟은 상위2비트를 10으로 설정해야 합니다.
의사 피톤은 다음과 같습니다.
newstring = ''
cont = 0
for each ch in string:
if cont:
if (ch >> 6) != 2: # high 2 bits are 10
# do whatever, e.g. skip it, or skip whole point, or?
else:
# acceptable continuation of multi-octlet char
newstring += ch
cont -= 1
else:
if (ch >> 7): # high bit set?
c = (ch << 1) # strip the high bit marker
while (c & 1): # while the high bit indicates another octlet
c <<= 1
cont += 1
if cont > 4:
# more than 4 octels not allowed; cope with error
if !cont:
# illegal, do something sensible
newstring += ch # or whatever
if cont:
# last utf-8 was not terminated, cope
이 논리는 php로 변환할 수 있어야 합니다.단, 부정한 문자가 생성되면 어떤 종류의 제거가 수행되어야 하는지 명확하지 않습니다.
최신 패치부터 Drupal의 Feeds JSON 파서 모듈까지:
//remove everything except valid letters (from any language)
$raw = preg_replace('/(?:\\\\u[\pL\p{Zs}])+/', '', $raw);
우려되는 경우 yes는 유효한 문자로 공백이 유지됩니다.
내가 필요한 걸 했어MySQL의 'utf8' 문자셋에 맞지 않는 요즘 널리 퍼진 이모티콘 문자를 제거하여 "SQLSTATE"와 같은 오류를 발생시켰습니다.HY000]: 일반 오류: 1366 문자열 값이 잘못되었습니다."
상세한 것에 대하여는, https://www.drupal.org/node/1824506#comment-6881382 를 참조해 주세요.
subst()는 멀티바이트 문자를 깨트릴 수 있습니다!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.substr($string, 0, 255)
사용자가 지정한 값이 데이터베이스에 맞는지 확인합니다.경우에 따라 멀티바이트 문자가 반으로 분할되어 "Intrect string value"로 데이터베이스 오류가 발생할 수 있습니다.
하면 .mb_substr($string,0,255)
MySQL 5는 괜찮지만 MySQL 4는 문자 대신 바이트 수를 세기 때문에 멀티바이트 문자 수에 따라서는 여전히 너무 깁니다.
이러한 문제를 방지하기 위해 다음 단계를 구현했습니다.
- 필드의 크기를 늘렸습니다(이 경우 변경 로그이므로 입력이 길어지지 않도록 할 수 없습니다).
- 는 아직 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ다를 요.
mb_substring
너무 - 위의 @Markus Jarderot에 의해 받아들여진 답변을 사용하여 길이 제한에 있는 멀티바이트 문자의 정말 긴 엔트리가 있는지 확인하고, 마지막에 멀티바이트 문자의 절반을 제거할 수 있는지 확인했습니다.
Unicode 기본 언어 플레인 외부에 있는 모든 Unicode 문자를 제거하려면 다음 절차를 수행합니다.
$str = preg_replace("/[^\\x00-\\xFFFF]/", "", $str);
저는 이 주제에 대해 제시된 많은 해결책을 시도해 보았지만, 제 경우엔 효과가 없었습니다.하지만 이 링크에서 좋은 솔루션을 찾았습니다.https://www.ryadel.com/en/php-skip-invalid-characters-utf-8-xml-file-string/
기본적으로 이 기능은 다음과 같이 해결되었습니다.
function sanitizeXML($string)
{
if (!empty($string))
{
// remove EOT+NOREP+EOX|EOT+<char> sequence (FatturaPA)
$string = preg_replace('/(\x{0004}(?:\x{201A}|\x{FFFD})(?:\x{0003}|\x{0004}).)/u', '', $string);
$regex = '/(
[\xC0-\xC1] # Invalid UTF-8 Bytes
| [\xF5-\xFF] # Invalid UTF-8 Bytes
| \xE0[\x80-\x9F] # Overlong encoding of prior code point
| \xF0[\x80-\x8F] # Overlong encoding of prior code point
| [\xC2-\xDF](?![\x80-\xBF]) # Invalid UTF-8 Sequence Start
| [\xE0-\xEF](?![\x80-\xBF]{2}) # Invalid UTF-8 Sequence Start
| [\xF0-\xF4](?![\x80-\xBF]{3}) # Invalid UTF-8 Sequence Start
| (?<=[\x0-\x7F\xF5-\xFF])[\x80-\xBF] # Invalid UTF-8 Sequence Middle
| (?<![\xC2-\xDF]|[\xE0-\xEF]|[\xE0-\xEF][\x80-\xBF]|[\xF0-\xF4]|[\xF0-\xF4][\x80-\xBF]|[\xF0-\xF4][\x80-\xBF]{2})[\x80-\xBF] # Overlong Sequence
| (?<=[\xE0-\xEF])[\x80-\xBF](?![\x80-\xBF]) # Short 3 byte sequence
| (?<=[\xF0-\xF4])[\x80-\xBF](?![\x80-\xBF]{2}) # Short 4 byte sequence
| (?<=[\xF0-\xF4][\x80-\xBF])[\x80-\xBF](?![\x80-\xBF]) # Short 4 byte sequence (2)
)/x';
$string = preg_replace($regex, '', $string);
$result = "";
$current;
$length = strlen($string);
for ($i=0; $i < $length; $i++)
{
$current = ord($string{$i});
if (($current == 0x9) ||
($current == 0xA) ||
($current == 0xD) ||
(($current >= 0x20) && ($current <= 0xD7FF)) ||
(($current >= 0xE000) && ($current <= 0xFFFD)) ||
(($current >= 0x10000) && ($current <= 0x10FFFF)))
{
$result .= chr($current);
}
else
{
$ret; // use this to strip invalid character(s)
// $ret .= " "; // use this to replace them with spaces
}
}
$string = $result;
}
return $string;
}
여러분 중 몇 명이 도움이 되길 바랍니다.
질문과는 조금 다릅니다만, Html Encode(string)를 사용하고 있습니다.
유사 코드 여기
var encoded = HtmlEncode(string);
encoded = Regex.Replace(encoded, "&#\d+?;", "");
var result = HtmlDecode(encoded);
입출력
"Headlight\x007E Bracket, { Cafe Racer<> Style, Stainless Steel 中文呢?"
"Headlight~ Bracket, { Cafe Racer<> Style, Stainless Steel 中文呢?"
완벽하지 않다는 걸 알지만, 내 일을 해 줘.
가장 정확한 솔루션은 아니지만 코드 한 줄로 작업을 수행할 수 있습니다.
echo str_replace("?","",(utf8_decode($str)));
utf8_decode
문자를 물음표로 변환합니다.
str_replace
물음표가 지워집니다.
static $preg = <<<'END'
%(
[\x09\x0A\x0D\x20-\x7E]
| [\xC2-\xDF][\x80-\xBF]
| \xE0[\xA0-\xBF][\x80-\xBF]
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
| \xED[\x80-\x9F][\x80-\xBF]
| \xF0[\x90-\xBF][\x80-\xBF]{2}
| [\xF1-\xF3][\x80-\xBF]{3}
| \xF4[\x80-\x8F][\x80-\xBF]{2}
)%xs
END;
if (preg_match_all($preg, $string, $match)) {
$string = implode('', $match[0]);
} else {
$string = '';
}
그것은 우리의 서비스에 효과가 있다
다음 소독은 나에게 효과가 있다.
$string = mb_convert_encoding($string, 'UTF-8', 'UTF-8');
$string = iconv("UTF-8", "UTF-8//IGNORE", $string);
아이콘v:
http://php.net/manual/en/function.iconv.php
PHP 자체에서 사용한 적은 없지만 명령줄에서 항상 잘 수행되었습니다.유효하지 않은 문자를 대체하도록 할 수 있습니다.
언급URL : https://stackoverflow.com/questions/1401317/remove-non-utf8-characters-from-string
'programing' 카테고리의 다른 글
C 프리프로세서에서 Mac OS X, iOS, Linux, Windows를 신뢰성 있게 검출하는 방법 (0) | 2023.01.10 |
---|---|
Programming Error: 스레드에서 생성된 SQLite 개체는 동일한 스레드에서만 사용할 수 있습니다. (0) | 2023.01.10 |
mysql에 한 테이블에서 다른 테이블로 데이터를 삽입합니다. (0) | 2023.01.10 |
파일의 선두에서 「」를 삭제하려면 어떻게 해야 합니까? (0) | 2023.01.10 |
Java에서 웹 페이지를 프로그래밍 방식으로 다운로드하는 방법 (0) | 2022.12.26 |