programing

문자열에서 utf8이 아닌 문자 제거

goodcopy 2023. 1. 10. 21:20
반응형

문자열에서 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년에 것을 합니다./uUTF-8 regex

" " " 을 사용하는 mb_convert_encoding($value, 'UTF-8', 'UTF-8')가 계속 됩니다.

이 방법은 다음과 같습니다.

  • 를 UTF-8로 모두 합니다.mb_convert_encoding
  • 다음과 같이 인쇄할 수 없는 모든 문자 제거\r,\x00NULL 바이트)및 제어 문자(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 입니다.\n0 ~ 의 0 ~31 의 newline 에 을 ./[^[:print:]\n]/u

https://cdn.shopify.com/s/files/1/1014/5789/files/Standard-ASCII-Table_large.jpg?10669400161723642407

와 함께 수 .\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는 문자 대신 바이트 수를 세기 때문에 멀티바이트 문자 수에 따라서는 여전히 너무 깁니다.

이러한 문제를 방지하기 위해 다음 단계를 구현했습니다.

  1. 필드의 크기를 늘렸습니다(이 경우 변경 로그이므로 입력이 길어지지 않도록 할 수 없습니다).
  2. 는 아직 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ다를 요.mb_substring 너무
  3. 위의 @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, &#123; Cafe Racer<> Style, Stainless Steel 中文呢?"
"Headlight~ Bracket, &#123; 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

반응형