Im को स्ट्रिंग से गैर-utf8 वर्णों को हटाने में समस्या है, जो ठीक से प्रदर्शित नहीं हो रहे हैं। वर्ण इस तरह हैं 0x97 0x61 0x6C 0x6F (हेक्स प्रतिनिधित्व)
उन्हें हटाने का सबसे अच्छा तरीका क्या है? नियमित अभिव्यक्ति या कुछ और?
Im को स्ट्रिंग से गैर-utf8 वर्णों को हटाने में समस्या है, जो ठीक से प्रदर्शित नहीं हो रहे हैं। वर्ण इस तरह हैं 0x97 0x61 0x6C 0x6F (हेक्स प्रतिनिधित्व)
उन्हें हटाने का सबसे अच्छा तरीका क्या है? नियमित अभिव्यक्ति या कुछ और?
जवाबों:
रेगेक्स दृष्टिकोण का उपयोग करना:
$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 वर्णों के अनुक्रम से मेल खाता है।
$regex = <<<'END'PHP <5.3.x के बजाय क्या उपयोग करना है ?
elseif (!empty($captures([2])) {और आपको !== ""खाली के बजाय का उपयोग करना चाहिए क्योंकि "0"खाली माना जाता है। इसके अलावा यह कार्य बहुत धीमा है, क्या यह तेजी से किया जा सकता है?
यदि आप utf8_encode()पहले से ही UTF8 स्ट्रिंग पर लागू होते हैं, तो यह एक विकृत UTF8 आउटपुट लौटाएगा।
मैंने एक फ़ंक्शन बनाया जो इस सभी मुद्दों को संबोधित करता है। यह है कहा जाता है Encoding::toUTF8()।
आपको यह जानने की जरूरत नहीं है कि आपके तार की एन्कोडिंग क्या है। यह लैटिन 1 (ISO8859-1), विंडोज -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);
मैंने एक और फ़ंक्शन शामिल किया है, एन्कोडिंग :: fixUTF8 (), जो हर UTF8 स्ट्रिंग को ठीक करेगा जो कि कई बार UTF8 में एन्कोड किए गए उत्पाद को दिखाता है।
उपयोग:
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
डाउनलोड:
आप mbstring का उपयोग कर सकते हैं:
$text = mb_convert_encoding($text, 'UTF-8', 'UTF-8');
... अमान्य वर्ण हटा देंगे।
<0x1a>
<0x1a>, हालांकि प्रिंट करने योग्य चरित्र नहीं है, यह पूरी तरह से वैध यूटीएफ -8 अनुक्रम है। आपके पास गैर-मुद्रण योग्य वर्णों के साथ समस्याएँ हो सकती हैं? इसे देखें: stackoverflow.com/questions/1176904/…
ini_set('mbstring.substitute_character', 'none');नहीं करना था अन्यथा मुझे परिणाम में प्रश्न चिह्न मिल रहे थे।
यह फ़ंक्शन सभी NON ASCII वर्णों को निकालता है, यह उपयोगी है लेकिन प्रश्न को हल नहीं कर रहा है:
यह मेरा कार्य है जो हमेशा काम करता है, एन्कोडिंग की परवाह किए बिना:
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?
íपते के क्षेत्र में चरित्र था जो एक वैध UTF-8 चरित्र तालिका है । मनोबल: एपीआई त्रुटि संदेशों पर भरोसा न करें :)
$text = iconv("UTF-8", "UTF-8//IGNORE", $text);
यह मैं उपयोग कर रहा हूं। बहुत अच्छा काम करने लगता है। Http://planetozh.com/blog/2005/01/remove-invalid-characters-in-utun-// से लिया गया
इसे इस्तेमाल करे:
$string = iconv("UTF-8","UTF-8//IGNORE",$string);
आइकनव मैनुअल के अनुसार , फंक्शन पहले पैरामीटर को इनपुट चारसेट, दूसरा पैरामीटर आउटपुट चारसेट के रूप में और तीसरा वास्तविक इनपुट स्ट्रिंग के रूप में लेगा।
यदि आप UTF-8 में इनपुट और आउटपुट दोनों को चारसेट में सेट करते हैं , और //IGNOREध्वज को आउटपुट चारसेट में जोड़ते हैं , तो फ़ंक्शन इनपुट स्ट्रिंग के सभी वर्णों को ड्रॉप (स्ट्रिप) कर देगा, जो आउटपुट चारसेट द्वारा प्रस्तुत नहीं किया जा सकता है। इस प्रकार, प्रभाव में इनपुट स्ट्रिंग को फ़िल्टर करना।
//IGNOREनोटिस को दबाने के लिए प्रतीत नहीं होता है कि अमान्य यूटीएफ -8 मौजूद है (जो निश्चित रूप से, मुझे पता है, और ठीक करना चाहते हैं)। मैनुअल में एक उच्च श्रेणी की टिप्पणी से लगता है कि यह कुछ वर्षों के लिए बग है।
iconv। @halfer हो सकता है कि आपका इनपुट डेटा utf-8 से न हो। एक अन्य विकल्प यह है कि एससीआई में फिर से रूपांतरण करने के लिए फिर से utf-8 पर वापस जाएं। मेरे मामले में मैं इस्तेमाल किया था iconvकी तरह$output = iconv("UTF-8//", "ISO-8859-1//IGNORE", $input );
पाठ में गैर-utf8 वर्ण हो सकता है । पहले करने की कोशिश करो:
$nonutf8 = mb_convert_encoding($nonutf8 , 'UTF-8', 'UTF-8');
आप इसके बारे में और अधिक यहाँ पढ़ सकते हैं: http://php.net/manual/en/function.mb-convert-encoding.php समाचार
PHP 5.5 के बाद से UConverter का उपयोग किया जा सकता है। यदि आप 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);
}
PHP 5.4 से अमान्य बाइट अनुक्रम को हटाने के लिए htmlspecialchars का उपयोग किया जा सकता है। Htmlspecialchars बाइट और सटीकता के बड़े आकार को संभालने के लिए preg_match से बेहतर है। नियमित अभिव्यक्ति का उपयोग करके बहुत सारे गलत कार्यान्वयन देखे जा सकते हैं।
function replace_invalid_byte_sequence3($str)
{
return htmlspecialchars_decode(htmlspecialchars($str, ENT_SUBSTITUTE, '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;
}
ord()0-255 की सीमा में परिणाम देता है। ifइस फ़ंक्शन में विशाल यूनिकोड पर्वतमाला के लिए परीक्षण करता है जो ord()कभी वापस नहीं आएगा। अगर कोई यह स्पष्ट करना चाहता है कि यह फ़ंक्शन उस तरीके से काम करता है जिस तरह से मैं अंतर्दृष्टि की सराहना करता हूं।
2019 में आपका स्वागत है और /uरेगेक्स में संशोधक जो आपके लिए UTF-8 मल्टीबाइट चार्ट संभालेंगे
यदि आप केवल उपयोग करते mb_convert_encoding($value, 'UTF-8', 'UTF-8')हैं तो भी आप अपनी स्ट्रिंग में गैर-प्रिंट करने योग्य वर्णों के साथ समाप्त हो जाएंगे
यह तरीका होगा:
mb_convert_encoding\r, जैसे \x00(NULL-बाइट) और अन्य नियंत्रण वर्णों के साथpreg_replacefunction utf8_filter(string $value): string{
return preg_replace('/[^[:print:]\n]/u', '', mb_convert_encoding($value, 'UTF-8', 'UTF-8'));
}
[:print:]सभी मुद्रण योग्य वर्णों और \nन्यूलाइन्स से मिलान करें और बाकी सब कुछ छीन लें
आप नीचे ASCII तालिका देख सकते हैं .. प्रिंट करने योग्य वर्ण 32 से 127 तक होते हैं, लेकिन नई लाइन \nनियंत्रण वर्णों का एक हिस्सा है जो 0 से 31 तक होती है इसलिए हमें regex में नई पंक्ति जोड़ना होगा/[^[:print:]\n]/u
आप रेगेक्स के माध्यम से स्ट्रिंग्स को प्रिंट करने योग्य रेंज जैसे \x7F(DEL), \x1B(Esc) आदि से बाहर भेजने की कोशिश कर सकते हैं और देख सकते हैं कि उनसे कैसे छीन लिया गया।
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";
}
php-mbstringडिफ़ॉल्ट रूप से php में पैक नहीं किया गया है।
$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'));
हाल ही में पैच से लेकर ड्रुपल के फ़ीड्स JSON पार्सर मॉड्यूल:
//remove everything except valid letters (from any language)
$raw = preg_replace('/(?:\\\\u[\pL\p{Zs}])+/', '', $raw);
यदि आप चिंतित हैं, तो यह मान्य वर्णों के रूप में रिक्त स्थान बनाए रखता है।
मुझे जो चाहिए था किया। यह आजकल के इमोजी-पात्रों को दूर करता है जो MySQL के 'utf8' वर्ण सेट में फिट नहीं होते हैं और जिसने मुझे "SQLSTATE [HY000]: सामान्य त्रुटि: 1366 गलत स्ट्रिंग मान" जैसी त्रुटियां दी हैं।
विवरण के लिए https://www.drupal.org/node/1824506#comment-6881382 देखें
iconvअब तक पुराने जमाने regexp आधारित तुलना में बेहतर है preg_replace, जो आजकल मान्य नहीं है।
ereg_replace(), क्षमा करें।
शायद सबसे सटीक समाधान नहीं है, लेकिन यह कोड की एक पंक्ति के साथ काम करता है:
echo str_replace("?","",(utf8_decode($str)));
utf8_decodeवर्णों को प्रश्न चिह्न में बदल देंगे;
str_replaceसवालिया निशान छीन लेगा।
तो नियम हैं कि पहले UTF-8 ऑक्टलेट में एक मार्कर के रूप में उच्च बिट सेट है, और फिर कितने अतिरिक्त ऑक्टलेट्स को इंगित करने के लिए 1 से 4 बिट्स; फिर प्रत्येक अतिरिक्त ऑक्टलेट्स में उच्च दो बिट्स 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 के लिए अनुवाद योग्य होना चाहिए। हालाँकि, यह स्पष्ट नहीं है कि एक बार विकृत चरित्र प्राप्त करने के बाद किस तरह की स्ट्रिपिंग की जानी है।
c = (ch << 1)(c & 1)पहली बार शून्य कर देगा , लूप को लंघन। परीक्षण शायद होना चाहिए(c & 128)
यूनिकोड मूल भाषा तल के बाहर सभी यूनिकोड वर्णों को हटाने के लिए:
$str = preg_replace("/[^\\x00-\\xFFFF]/", "", $str);
प्रश्न के लिए थोड़ा अलग है, लेकिन मैं जो कर रहा हूं वह HtmlEncode (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 中文呢?"
मुझे पता है कि यह सही नहीं है, लेकिन मेरे लिए काम करता है।
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 = '';
}
यह हमारी सेवा पर काम करता है
कैसे आइकॉन के बारे में:
http://php.net/manual/en/function.iconv.php
यह PHP के अंदर ही इस्तेमाल नहीं किया है, लेकिन यह हमेशा कमांड लाइन पर मेरे लिए अच्छा प्रदर्शन किया है। आप इसे अमान्य वर्ण स्थानापन्न करने के लिए प्राप्त कर सकते हैं।