PHP: วิธีลบอักขระที่ไม่สามารถพิมพ์ได้ทั้งหมดในสตริง?


161

ฉันคิดว่าฉันต้องลบตัวอักษร 0-31 และ 127

มีฟังก์ชั่นหรือชิ้นส่วนของรหัสที่จะทำเช่นนี้ได้อย่างมีประสิทธิภาพ

คำตอบ:


355

ASCII 7 บิต?

หากควานหาของคุณเพิ่งลงจอดในปี 1963 และคุณต้องการตัวอักษร ASCII ที่พิมพ์ได้ 7 บิตคุณสามารถคัดลอกทุกอย่างตั้งแต่ 0-31 และ 127-255 ด้วยวิธีนี้:

$string = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $string);

มันตรงกับทุกอย่างในช่วง 0-31, 127-255 และลบออก

ASCII ขยาย 8 บิต?

คุณล้มลงใน Hot Tub Time Machine และคุณกลับมาในยุคแปด หากคุณมี ASCII 8 บิตบางรูปแบบคุณอาจต้องการให้ตัวอักษรอยู่ในช่วง 128-255 ปรับง่าย - เพียงมองหา 0-31 และ 127

$string = preg_replace('/[\x00-\x1F\x7F]/', '', $string);

UTF-8?

อายินดีต้อนรับกลับสู่ศตวรรษที่ 21 หากคุณมีสตริงที่เข้ารหัส UTF-8 คุณสามารถใช้/u ตัวดัดแปลงบน regex ได้

$string = preg_replace('/[\x00-\x1F\x7F]/u', '', $string);

สิ่งนี้จะลบ 0-31 และ 127 ซึ่งทำงานใน ASCII และ UTF-8 เพราะทั้งคู่ใช้ช่วงชุดควบคุมเดียวกัน (ตามที่ระบุโดย mgutt ด้านล่าง) พูดอย่างเคร่งครัดสิ่งนี้จะทำงานโดยไม่มี/uตัวแก้ไข แต่มันทำให้ชีวิตง่ายขึ้นถ้าคุณต้องการลบตัวอักษรอื่น ...

หากคุณกำลังจัดการกับ Unicode อาจมีองค์ประกอบที่ไม่ใช่การพิมพ์จำนวนมากแต่ลองพิจารณาองค์ประกอบง่ายๆ: NO-BREAK SPACE (U + 00A0)

ในสตริง UTF-8 0xC2A0นี้จะได้รับการเข้ารหัสเป็น คุณสามารถค้นหาและลบลำดับที่เฉพาะเจาะจงได้ แต่เมื่อมีการ/uปรับเปลี่ยนคุณสามารถเพิ่มลง\xA0ในคลาสอักขระได้:

$string = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $string);

ภาคผนวก: แล้ว str_replace ล่ะ?

preg_replace ค่อนข้างมีประสิทธิภาพ แต่ถ้าคุณทำสิ่งนี้มากคุณสามารถสร้างชุดอักขระที่คุณต้องการลบและใช้ str_replace ตามที่ระบุไว้โดย mgutt ด้านล่างเช่น

//build an array we can re-use across several operations
$badchar=array(
    // control characters
    chr(0), chr(1), chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8), chr(9), chr(10),
    chr(11), chr(12), chr(13), chr(14), chr(15), chr(16), chr(17), chr(18), chr(19), chr(20),
    chr(21), chr(22), chr(23), chr(24), chr(25), chr(26), chr(27), chr(28), chr(29), chr(30),
    chr(31),
    // non-printing characters
    chr(127)
);

//replace the unwanted chars
$str2 = str_replace($badchar, '', $str);

อย่างสังหรณ์ใจดูเหมือนว่ามันจะเร็ว แต่ก็ไม่ได้เป็นเช่นนั้นเสมอไปคุณควรจะเปรียบเทียบเพื่อดูว่ามันช่วยคุณได้หรือไม่ ฉันได้ทำการวัดประสิทธิภาพตามความยาวสตริงที่หลากหลายด้วยข้อมูลแบบสุ่มและรูปแบบนี้ก็ปรากฏขึ้นโดยใช้ php 7.0.12

     2 chars str_replace     5.3439ms preg_replace     2.9919ms preg_replace is 44.01% faster
     4 chars str_replace     6.0701ms preg_replace     1.4119ms preg_replace is 76.74% faster
     8 chars str_replace     5.8119ms preg_replace     2.0721ms preg_replace is 64.35% faster
    16 chars str_replace     6.0401ms preg_replace     2.1980ms preg_replace is 63.61% faster
    32 chars str_replace     6.0320ms preg_replace     2.6770ms preg_replace is 55.62% faster
    64 chars str_replace     7.4198ms preg_replace     4.4160ms preg_replace is 40.48% faster
   128 chars str_replace    12.7239ms preg_replace     7.5412ms preg_replace is 40.73% faster
   256 chars str_replace    19.8820ms preg_replace    17.1330ms preg_replace is 13.83% faster
   512 chars str_replace    34.3399ms preg_replace    34.0221ms preg_replace is  0.93% faster
  1024 chars str_replace    57.1141ms preg_replace    67.0300ms str_replace  is 14.79% faster
  2048 chars str_replace    94.7111ms preg_replace   123.3189ms str_replace  is 23.20% faster
  4096 chars str_replace   227.7029ms preg_replace   258.3771ms str_replace  is 11.87% faster
  8192 chars str_replace   506.3410ms preg_replace   555.6269ms str_replace  is  8.87% faster
 16384 chars str_replace  1116.8811ms preg_replace  1098.0589ms preg_replace is  1.69% faster
 32768 chars str_replace  2299.3128ms preg_replace  2222.8632ms preg_replace is  3.32% faster

การกำหนดเวลาใช้สำหรับการวนซ้ำ 10,000 ครั้ง แต่สิ่งที่น่าสนใจกว่าคือความแตกต่างสัมพัทธ์ มากถึง 512 ตัวฉันเห็น preg_replace เสมอชนะ ในช่วง 1-8kb, str_replace มีขอบเล็กน้อย

ฉันคิดว่ามันเป็นผลลัพธ์ที่น่าสนใจรวมถึงที่นี่ด้วย สิ่งสำคัญคือไม่ใช้ผลลัพธ์นี้และใช้เพื่อตัดสินใจว่าจะใช้วิธีใด แต่เพื่อเปรียบเทียบกับข้อมูลของคุณเองแล้วตัดสินใจ


14
หากคุณต้องการพิจารณาการขึ้นบรรทัดใหม่ให้เปลี่ยนนิพจน์เป็นสิ่งนี้ (ค้นหาผังงานพิมพ์): preg_replace (/ [^ \ x0A \ x20- \ x7-], '', $ string);
Nick

12
@Dalin ไม่มีสิ่งเช่นตัวอักษร "UTF-8" มีสัญลักษณ์ / ตัวอักษร Unicode และ UTF-8 เป็นการเข้ารหัสที่สามารถแสดงถึงพวกเขาทั้งหมด คุณตั้งใจจะพูดว่านี่ไม่ได้ผลกับตัวละครที่อยู่นอกชุดอักขระ ASCII
งัด Bynens

3
หากคุณต้องการจับคู่อักขระ Unicode ด้านบน \ xFF ให้ใช้ \ x {####}
Peter Olson

คุณพลาด \ x7F (127) ซึ่งเป็นอักขระที่ไม่สามารถพิมพ์ได้
Mubashar

สิ่งนี้จะลบตัวอักษรภาษาอาหรับทางออกที่ไม่ดี
Ayman Hussein

141

คำตอบอื่น ๆ อีกมากมายที่นี่ไม่ได้คำนึงถึงตัวอักษร unicode (เช่นöäüßйȝîûηыეமிᚉ⠛) ในกรณีนี้คุณสามารถใช้สิ่งต่อไปนี้:

$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/u', '', $string);

มีคลาสอักขระแปลก ๆ อยู่ในช่วง\x80-\x9F(เหนือช่วงอักขระ ASCII 7 บิต) ที่เป็นตัวควบคุมทางเทคนิค แต่เมื่อเวลาผ่านไปได้ถูกนำไปใช้ในทางที่ผิดสำหรับอักขระที่พิมพ์ได้ หากคุณไม่มีปัญหาใด ๆ กับสิ่งเหล่านี้คุณสามารถใช้:

$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $string);

หากคุณต้องการตัดการป้อนบรรทัดการขึ้นบรรทัดใหม่แท็บการเว้นวรรคแบบไม่แตกและยัติภังค์แบบอ่อนคุณสามารถใช้:

$string = preg_replace('/[\x00-\x1F\x7F-\xA0\xAD]/u', '', $string);

โปรดทราบว่าคุณต้องใช้เครื่องหมายคำพูดเดี่ยวสำหรับตัวอย่างด้านบน

หากคุณต้องการตัดทุกอย่างยกเว้นตัวอักษร ASCII พื้นฐานที่พิมพ์ได้ (ตัวอักษรตัวอย่างทั้งหมดด้านบนจะถูกปล้น) คุณสามารถใช้:

$string = preg_replace( '/[^[:print:]]/', '',$string);

สำหรับการอ้างอิงดูhttp://www.fileformat.info/info/charset/UTF-8/list.htm


1
regexp ของคุณจัดการกับ UTF8 ตัวอักษรได้ดี แต่จะแยกอักขระที่ไม่ใช่ "พิเศษ" UTF8; ชอบç, üและö '/[\x00-\x1F\x80-\xC0]/u'ทำให้พวกเขาเหมือนเดิม; แต่ยังมีสัญลักษณ์ (F7) และการคูณ (D7)
Hazar

@ ฮาซาร์ใช่คุณถูกต้อง \ x80- \ xFF ถอดออกมากเกินไป แต่ \ x80- \ xC0 ยังคงเข้มงวดเกินไป นี่จะเป็นตัวอักษรที่พิมพ์ได้อื่น ๆ เช่น©£± สำหรับการอ้างอิงโปรดดูutf8-chartable.de
Dalin

1
@TimMalone เนื่องจาก PHP จะขยายลำดับอักขระ: php.net/manual/en/…ดังนั้น regex จะไม่เห็นช่วงที่คุณพยายามบอก
Dalin

1
สิ่งที่เกี่ยวกับ 7F ไม่ควร\x7F-\x9Fหรือ
เบล

1
ฉันลองมากฉันลองทุกฟังก์ชั่นการเข้ารหัสที่มีอยู่ใน PHP จาก regex ถึง mb_ ถึง htmlspecialchars เป็นต้นไม่มีอะไรลบอักขระควบคุมออกขอบคุณสำหรับการลงทุน
จอห์

29

เริ่มต้นด้วย PHP 5.2 เรายังสามารถเข้าถึง filter_var ซึ่งฉันไม่เคยเห็นมีการกล่าวถึงดังนั้นฉันคิดว่าฉันจะทิ้งมันไว้ที่นั่น หากต้องการใช้ filter_var เพื่อตัดอักขระที่ไม่สามารถพิมพ์ได้ <32 และ> 127 คุณสามารถทำได้

กรองอักขระ ASCII ด้านล่าง 32

$string = filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);

กรองอักขระ ASCII ด้านบน 127

$string = filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_HIGH);

ตัดทั้งสอง:

$string = filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW|FILTER_FLAG_STRIP_HIGH);

นอกจากนี้คุณยังสามารถเข้ารหัสอักขระต่ำ HTML (ขึ้นบรรทัดใหม่แท็บ ฯลฯ ) ในขณะที่การลอกสูง:

$string = filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_LOW|FILTER_FLAG_STRIP_HIGH);

นอกจากนี้ยังมีตัวเลือกสำหรับการลอก HTML, ฆ่าเชื้ออีเมลและ URL ฯลฯ ดังนั้นตัวเลือกมากมายสำหรับการฆ่าเชื้อ (ดึงข้อมูล) และการตรวจสอบความถูกต้อง (คืนเท็จถ้าไม่ถูกต้องแทนที่จะลอกแบบเงียบ ๆ )

การฆ่าเชื้อ: http://php.net/manual/en/filter.filters.sanitize.php

การตรวจสอบความถูกต้อง: http://php.net/manual/en/filter.filters.validate.php

อย่างไรก็ตามยังคงมีปัญหาว่า FILTER_FLAG_STRIP_LOW จะตัดการขึ้นบรรทัดใหม่และการขึ้นบรรทัดใหม่ซึ่งสำหรับ textarea เป็นอักขระที่ถูกต้องสมบูรณ์ ... ดังนั้นฉันคิดว่า Regex บางคำตอบยังคงมีความจำเป็นในบางครั้งเช่นหลังจากตรวจสอบเรื่องนี้ ด้ายฉันวางแผนที่จะทำสิ่งนี้สำหรับ textareas:

$string = preg_replace( '/[^[:print:]\r\n]/', '',$input);

ดูเหมือนว่าจะสามารถอ่านได้มากกว่าจำนวน regexes ที่แยกออกตามช่วงตัวเลข



18

ง่ายกว่านี้:

$ string = preg_replace ('/ [^ [: cntrl:]] /', '', $ string);


5
สิ่งนี้ยังตัดการป้อนบรรทัดการขึ้นบรรทัดใหม่และอักขระ UTF8
Dalin

5
@Dalin ไม่มีสิ่งเช่นตัวอักษร "UTF-8" มีสัญลักษณ์ / ตัวอักษร Unicode และ UTF-8 เป็นการเข้ารหัสที่สามารถแสดงถึงพวกเขาทั้งหมด คุณตั้งใจจะพูดว่านี่จะลอกอักขระที่อยู่นอกช่วง ASCIIเช่นกัน
งัด Bynens

1
กินตัวอักษรภาษาอาหรับ :)
Rolf

16

โซลูชันทั้งหมดทำงานได้บางส่วนและอาจต่ำกว่านั้นไม่ครอบคลุมทุกกรณี ปัญหาของฉันพยายามแทรกสตริงลงในตาราง utf8 mysql สตริง (และไบต์) ทั้งหมดสอดคล้องกับ utf8 แต่มีลำดับที่ไม่ดีหลายประการ ฉันคิดว่าส่วนใหญ่เป็นการควบคุมหรือการจัดรูปแบบ

function clean_string($string) {
  $s = trim($string);
  $s = iconv("UTF-8", "UTF-8//IGNORE", $s); // drop all non utf-8 characters

  // this is some bad utf-8 byte sequence that makes mysql complain - control and formatting i think
  $s = preg_replace('/(?>[\x00-\x1F]|\xC2[\x80-\x9F]|\xE2[\x80-\x8F]{2}|\xE2\x80[\xA4-\xA8]|\xE2\x81[\x9F-\xAF])/', ' ', $s);

  $s = preg_replace('/\s+/', ' ', $s); // reduce all multiple whitespace to a single space

  return $s;
}

เพื่อทำให้รุนแรงขึ้นปัญหาคือตารางเทียบกับเซิร์ฟเวอร์กับการเชื่อมต่อกับการแสดงผลของเนื้อหาเช่น กล่าวไว้ที่นี่เล็กน้อย


1
คนเดียวที่ผ่านการทดสอบทุกหน่วยของฉันยอดเยี่ยม!
Korri

\ xE2 \ x80 [\ xA4- \ xA8] (หรือ 226.128. [164-168]) - ผิดลำดับรวมสัญลักษณ์ที่พิมพ์ได้ถัดไป: อักขระ Unicode 'ONE DOT LEADER' (U + 2024), อักขระ Unicode 'TWO DOT LEADER '(U + 2025), อักขระ Unicode' HORIZONTAL ELLIPSIS '(U + 2026), อักขระ Unicode' HYPHENATION POINT '(U + 2027) และมีเพียงหนึ่งที่ไม่สามารถพิมพ์ได้: อักขระ Unicode 'LINE SEPARATOR' (U + 2028) รายการถัดไปไม่สามารถพิมพ์ได้เช่นกัน: อักขระ Unicode 'PARAGRAPH SEPARATOR' (U + 2029) ดังนั้นแทนที่ลำดับด้วย: \ xE2 \ x80 [\ xA8- \ xA9] \ xE2 \ x80 [\ xA8- \ xA9] เพื่อลบ LINE SEPARATOR และ PARAGRAPH SEPARATOR
MingalevME

นี่เป็นทางออกที่ดีที่สุดที่ฉันสามารถหาได้ แต่ฉันยังต้องเพิ่ม$s = preg_replace('/(\xF0\x9F[\x00-\xFF][\x00-\xFF])/', ' ', $s);เพราะตัวละครอิโมจิทั้งหมดสับสนวุ่นวาย mysql
Joe Black

9

รุ่นที่รองรับ UTF-8 ของฉัน:

preg_replace('/[^\p{L}\s]/u','',$value);


7
สิ่งนี้จะลบตัวอักษรเช่นเครื่องหมายคำพูดวงเล็บ ฯลฯ ซึ่งเป็นตัวอักษรที่พิมพ์ได้อย่างแน่นอน
Gajus

มันวิเศษมาก! มันช่วยชีวิตฉันสับสนในขณะที่พิมพ์ตัวอักษรภาษาอาหรับทำงานเหมือนแชมป์ :)
krishna

6

คุณสามารถใช้การแสดงปกติเพื่อลบทุกอย่างนอกเหนือจากตัวละครที่คุณต้องการเก็บไว้:

$string=preg_replace('/[^A-Za-z0-9 _\-\+\&]/','',$string);

แทนที่ทุกอย่างที่ไม่ใช่ (^) ตัวอักษร AZ หรือ az ตัวเลข 0-9, ช่องว่าง, ขีดล่าง, hypen, plus และเครื่องหมาย - ไม่มีอะไร (เช่นลบออก)


5
preg_replace('/(?!\n)[\p{Cc}]/', '', $response);

สิ่งนี้จะลบอักขระควบคุมทั้งหมด ( http://uk.php.net/manual/en/regexp.reference.unicode.php ) ออกจาก\nอักขระบรรทัดใหม่ จากประสบการณ์ของฉันตัวควบคุมเป็นตัวละครที่มักทำให้เกิดปัญหาการพิมพ์


1
มันใช้งานได้สมบูรณ์แบบสำหรับฉัน! ฉันเพิ่มเฉพาะ/uสำหรับ UTF-8 chars คุณช่วยอธิบายส่วนแรก(?!\n)ทำอะไรได้บ้าง
Marcio Mazzucato

4

หากต้องการตัดอักขระที่ไม่ใช่ ASCII ทั้งหมดออกจากสตริงอินพุต

$result = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $string);

รหัสนั้นจะลบตัวอักษรใด ๆ ในช่วงเลขฐานสิบหก 0-31 และ 128-255 เหลือเพียงตัวอักษรฐานสิบหก 32-127 ในสตริงผลลัพธ์ที่ฉันเรียก $ result ในตัวอย่างนี้


3

คำตอบของ @PaulDixon คือผิดทั้งหมดเพราะมันเอาพิมพ์ อักขระ ASCII ขยาย 128-255!ได้รับการแก้ไขบางส่วน ฉันไม่รู้ว่าทำไมเขายังต้องการลบ 128-255 จากชุด ASCII แบบ 7 บิต 127 ตัวอักษรเนื่องจากมันไม่มีอักขระ ASCII ที่ขยายเพิ่ม

แต่ในที่สุดมันก็สำคัญที่จะไม่ลบ 128-255 เพราะตัวอย่างเช่นchr(128)( \x80) คือเครื่องหมายยูโรใน ASCII 8 บิตและแบบอักษร UTF-8 จำนวนมากใน Windows แสดงเครื่องหมายยูโรและ Android เกี่ยวกับการทดสอบของฉันเอง

และจะฆ่าอักขระ UTF-8 จำนวนมากหากคุณลบ ASCII chars 128-255 ออกจากสตริง UTF-8 (อาจเป็นไบต์เริ่มต้นของอักขระหลายไบต์ UTF-8) ดังนั้นอย่าทำอย่างนั้น! อักขระเหล่านี้เป็นอักขระตามกฎหมายอย่างสมบูรณ์ในระบบไฟล์ที่ใช้ในปัจจุบันทั้งหมด ช่วงลิขสิทธิ์เพียงอย่างเดียวคือ 0-31

ให้ใช้สิ่งนี้เพื่อลบอักขระที่ไม่สามารถพิมพ์ได้ 0-31 และ 127:

$string = preg_replace('/[\x00-\x1F\x7F]/', '', $string);

มันทำงานใน ASCII และ UTF-8เพราะทั้งสองร่วมกันเดียวกันช่วงการควบคุมชุด

เร็วที่สุดทางเลือกslower¹โดยไม่ต้องใช้การแสดงออกปกติ:

$string = str_replace(array(
    // control characters
    chr(0), chr(1), chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8), chr(9), chr(10),
    chr(11), chr(12), chr(13), chr(14), chr(15), chr(16), chr(17), chr(18), chr(19), chr(20),
    chr(21), chr(22), chr(23), chr(24), chr(25), chr(26), chr(27), chr(28), chr(29), chr(30),
    chr(31),
    // non-printing characters
    chr(127)
), '', $string);

หากคุณต้องการที่จะให้ตัวละครช่องว่างทั้งหมด\t, \nและ\rแล้วเอาchr(9), chr(10)และchr(13)จากรายการนี้ หมายเหตุ: ช่องว่างตามปกติคือchr(32)มันอยู่ในผลลัพธ์ ตัดสินใจด้วยตัวเองหากคุณต้องการลบพื้นที่ที่ไม่ทำลายchr(160)เนื่องจากอาจทำให้เกิดปัญหาได้

¹ทดสอบโดย @PaulDixon และตรวจสอบด้วยตัวเอง


2

เกี่ยวกับ:

return preg_replace("/[^a-zA-Z0-9`_.,;@#%~'\"\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:\-\s\\\\]+/", "", $data);

ช่วยให้ฉันควบคุมสิ่งที่ฉันต้องการรวมได้อย่างสมบูรณ์


0

anwser ที่ทำเครื่องหมายไว้นั้นสมบูรณ์แบบ แต่มันหายไปจากตัวละคร 127 (DEL) ซึ่งเป็นตัวละครที่ไม่สามารถพิมพ์ได้

คำตอบของฉันจะเป็น

$string = preg_replace('/[\x00-\x1F\x7f-\xFF]/', '', $string);

คำตอบนี้ก็ผิดเช่นกัน ดู: stackoverflow.com/a/42058165/318765
mgutt

คำตอบข้างต้นเป็นคำชมเชยสำหรับคำตอบดั้งเดิมซึ่งเพิ่มอักขระ "ลบ" เท่านั้น
Mubashar

0

"cedivad" แก้ไขปัญหาสำหรับฉันด้วยผลลัพธ์ที่ถาวรของตัวอักษรสวีเดนÅÄÖ

$text = preg_replace( '/[^\p{L}\s]/u', '', $text );

ขอบคุณ!


0

สำหรับทุกคนที่ยังคงมองหาวิธีการทำเช่นนี้โดยไม่ต้องลบตัวอักษรที่ไม่สามารถพิมพ์ออกมาได้ แต่จะช่วยให้พวกเขาหลุดรอดออกไปได้ อย่าลังเลที่จะปรับปรุงมัน! อักขระจะถูกหลบหนีไปที่ \\ x [A-F0-9] [A-F0-9]

โทรเช่น:

$escaped = EscapeNonASCII($string);

$unescaped = UnescapeNonASCII($string);

<?php 
  function EscapeNonASCII($string) //Convert string to hex, replace non-printable chars with escaped hex
    {
        $hexbytes = strtoupper(bin2hex($string));
        $i = 0;
        while ($i < strlen($hexbytes))
        {
            $hexpair = substr($hexbytes, $i, 2);
            $decimal = hexdec($hexpair);
            if ($decimal < 32 || $decimal > 126)
            {
                $top = substr($hexbytes, 0, $i);
                $escaped = EscapeHex($hexpair);
                $bottom = substr($hexbytes, $i + 2);
                $hexbytes = $top . $escaped . $bottom;
                $i += 8;
            }
            $i += 2;
        }
        $string = hex2bin($hexbytes);
        return $string;
    }
    function EscapeHex($string) //Helper function for EscapeNonASCII()
    {
        $x = "5C5C78"; //\x
        $topnibble = bin2hex($string[0]); //Convert top nibble to hex
        $bottomnibble = bin2hex($string[1]); //Convert bottom nibble to hex
        $escaped = $x . $topnibble . $bottomnibble; //Concatenate escape sequence "\x" with top and bottom nibble
        return $escaped;
    }

    function UnescapeNonASCII($string) //Convert string to hex, replace escaped hex with actual hex.
    {
        $stringtohex = bin2hex($string);
        $stringtohex = preg_replace_callback('/5c5c78([a-fA-F0-9]{4})/', function ($m) { 
            return hex2bin($m[1]);
        }, $stringtohex);
        return hex2bin(strtoupper($stringtohex));
    }
?>

0

ฉันแก้ไขปัญหาสำหรับ UTF8 โดยใช้https://github.com/neitanod/forceutf8

use ForceUTF8\Encoding;

$string = Encoding::fixUTF8($string);

1
lib นี้แปลงอักขระที่เน้นเสียง UTF-8 และอิโมติคอน UTF-8 เป็น "?" สัญลักษณ์ ปัญหาร้ายแรงเป็นธรรมน่าเสียดาย
ChristoKiwi

0

regex ในคำตอบที่เลือกล้มเหลวสำหรับ Unicode: 0x1d (with php 7.4)

ทางออก:

<?php
        $ct = 'différents'."\r\n test";

        // fail for Unicode: 0x1d
        $ct = preg_replace('/[\x00-\x1F\x7F]$/u', '',$ct);

        // work for Unicode: 0x1d
        $ct =  preg_replace( '/[^\P{C}]+/u', "",  $ct);

        // work for Unicode: 0x1d and allow line break
        $ct =  preg_replace( '/[^\P{C}\n]+/u', "",  $ct);

        echo $ct;

จาก: UTF 8 String ลบอักขระที่มองไม่เห็นทั้งหมดยกเว้นขึ้นบรรทัดใหม่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.