ตัวละครนี้คืออะไร: '*'?


48

เพื่อนวางคำสั่งเป็นหย่อน*ห้องแชทที่มีตัวอักษร ดูเหมือนว่าจะเป็นเรื่องปกติ*แต่ไม่ใช่:

$ uniprops '*​'
uniprops: no character named ‹*​›

แม้ว่าฉันจะใช้unipropsเครื่องหมายดอกจันที่ฉันได้รับเมื่อพิมพ์บนเครื่องของฉันฉันจะได้รับ:

$ uniprops '*'
U+002A ‹*› \N{ASTERISK}
    \pP \p{Po}
    All Any ASCII Assigned Basic_Latin Punct Is_Punctuation Common Zyyy Po P
       Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Other_Punctuation
       Pat_Syn Pattern_Syntax PatSyn POSIX_Graph POSIX_Print POSIX_Punct Print
       X_POSIX_Print Punctuation Unicode X_POSIX_Punct

ฉันยังสามารถเห็นว่ามันไม่ใช่เครื่องหมายดอกจันจริง ๆ โดยการส่งผ่านod:

$ printf '*​' | od -c
0000000   * 342 200 213
0000004

ในขณะที่คนปกติให้:

$ printf '*' | od -c
0000000   *
0000001

นี่คือตัวละครลึกลับที่มีขนาดใหญ่ขึ้นอีกเล็กน้อย:

* * * *

และเครื่องหมายดอกจันปกติ (ใช่มันมีลักษณะเหมือนกัน):

* * * *

ดังนั้นunipropsไม่ทราบว่านี่คืออะไรและผมก็ไม่สามารถค้นหาได้ในhttp://www.fileformat.info/อย่างใดอย่างหนึ่ง ฉันรู้ว่าเพื่อนที่วางมันไว้บน OS X (ฉันอยู่บน Linux) และมันทำงานบนระบบของพวกเขาในฐานะดอกจันปกติ ฉันสมมติว่า Slack เปลี่ยนไป ดังนั้นไม่มีใครมีความคิดใด ๆ ว่าตัวละครนั้นคืออะไร?

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


unipropsเป็นสคริปต์เล็ก ๆ ที่เรียบร้อยรวมอยู่ในUnicode::Tussleโมดูล Perl ซึ่งระบุและพิมพ์ข้อมูลเกี่ยวกับตัวละครที่คุณให้


ไม่สามารถทำซ้ำได้ ฉันใช้ord("*")สตริงที่คุณวางและ*คีย์เนทีฟและได้หมายเลขเดียวกันสำหรับทั้งคู่ (42)
March Ho

7
@MarchHo เครื่องยนต์เอ่อ SE ดูเหมือนว่าจะกินมัน ฉันทดสอบก่อนที่จะโพสต์และสามารถคัดลอกอักขระแปลก ๆ (แม้ว่าฉันเริ่มเข้าใจว่าปัญหาคือมีตัวอักษรพิเศษไม่ใช่ตัวอักษรพิมพ์เพิ่ม) แต่ฉันไม่สามารถคัดลอกจากคำถามที่โพสต์ได้ คุณต้องคลิกที่ลิงค์แก้ไขและคัดลอกจากที่นั่น
terdon

2
อย่างผิดปกติในแอพ Android ศูนย์ที่มีพื้นที่จะปรากฏขึ้นราวกับว่ามันเป็นพื้นที่ปกติ
Derobert

1
ที่น่าสนใจเมื่อฉันวางจาก 'แก้ไข' เข้ากับขั้วของฉันจะแสดงไว้เป็นurxvt *<200b>
bodo

หากคุณคัดลอกจากส่วนรหัสของคุณเช่นบรรทัด uniprops มันก็อปปี้ตกลงโดยไม่ต้องไปที่แหล่งคำถาม (การวางลงใน Python3 ล่ามก็จะแสดงเหมือน'*\u200b'กัน)
TessellatingHeckler

คำตอบ:


71

วางล้มเหลวไม่ได้เพราะเครื่องหมายดอกจันซึ่งเป็นเครื่องหมายดอกจันปกติอย่างสมบูรณ์แบบ แต่เนื่องจากอักขระ Unicode U เนื่องจากตัวละครเป็น a ZERO WIDTH SPACEจึงไม่แสดงเมื่อคัดลอก

ใช้รหัสหลาม:

stro=u"'*​'?"
def uniconv(text):
    return " ".join(hex(ord(char)) for char in text)
uniconv(stro)

ฟังก์ชั่นuniconvแปลงสตริงอินพุต (ในกรณีนี้u"'*'?") ให้เป็นโค้ดเพจ Unicode ที่เทียบเท่าในรูปแบบเลขฐานสิบหก uคำนำหน้าสตริงระบุสตริงเป็นสตริง Unicode

ฉันสามารถรับเอาท์พุท:

0x27 0x2a 0x200b 0x27 0x3f

เราสามารถเห็นได้ชัดเจนว่า0x27, 0x2aและ0x3fเป็น ASCII / Unicode ค่าฐานสิบหกสำหรับตัวละคร', *และ?ตามลำดับ ใบ0x200bนั้นจึงระบุตัวละคร

โปรดทราบว่ารหัส Python เมื่อวางลงในเนื้อความได้ลบอักขระ U + 200B โดยซอฟต์แวร์ Markdown ของ SE เพื่อให้ได้ผลลัพธ์ที่คาดหวังคุณต้องคัดลอกโดยตรงจากชื่อโดยใช้มุมมองแก้ไข


5
การแทนที่strด้วยhexจะส่งออก codepoints เป็นเลขฐานสิบหกทำให้ง่ายต่อการจดจำหรือค้นหา
deltab

นอกจากนี้ยังมีโมดูลหลามเฉพาะunicodedataที่คุณสามารถสอบถามชื่อตัวละครหมวดหมู่และอื่น ๆ ได้
bodo

4
ตัวละคร ZERO WIDTH SPACE และ ZERO WIDTH JOINER นั้นสะดวกต่อการใช้งานกับระบบการแสดงความคิดเห็นที่พยายามที่จะบล็อกคำสแปมทั่วไป ตัวอย่างเช่นหากต้องการชี้ให้เห็นว่าเบอร์นีแซนเดอร์สได้รับเลือกเข้าสู่วุฒิสภาในฐานะนักสังคมนิยม (โดยไม่สะดุดกับดักสแปมสำหรับ "เซียลิส") เขียนเป็น "โซเชียล & zwj; อลิสต์" หากหน่วยงาน HTML นั้นเคารพ หรือเทียบเท่าหากไม่ได้
Monty Harder

27

ด้วยความช่วยเหลือของ @Rinzwind ในห้องสนทนา Ask Ubuntu ฉันคิดว่าปัญหาไม่ใช่ตัวละครเลย บันทึกผลลัพธ์ของod:

$ printf '*​' | od -c
0000000   * 342 200 213
0000004

342 200 213เป็นตัวแทนฐานแปดของตัวละครอื่นและเราสามารถใช้เว็บไซต์นี้จะมองมันขึ้นมา:

Character                   ​               
Character name                              ZERO WIDTH SPACE
Hex code point                              200B
Decimal code point                          8203
Hex UTF-8 bytes                             E2 80 8B
Octal UTF-8 bytes                           342 200 213
UTF-8 bytes as Latin-1 characters bytes     â <80> <8B>

สิ่งที่ฉันมีก็คือตัวละครยูนิโค้ดสองตัวคือ*พื้นที่ว่างปกติและความกว้างเป็นศูนย์


6
printf '\342\200\213' | uninameวิธีการที่จะทำเช่นนั้นได้ก็คือ (ชื่อเดียวกันมาจากแพ็คเกจ uniutils)
deltab

1
จากเว็บไซต์นี้คุณสามารถมีการแปลงรูปแบบที่แตกต่างกัน: สำหรับ HEX มันให้002A 200B, สำหรับ utf-8 2A E2 80 8Bสำหรับ utf-16 002A 200B...
Hastur
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.