首頁 > Java > java教程 > 要記住的邊緣情況。部分文字

要記住的邊緣情況。部分文字

王林
發布: 2024-08-09 06:41:22
原創
1082 人瀏覽過

Edge Cases to Keep in Mind. Part  Text

無論您是軟體開發人員、文案撰稿人還是只是寫電子郵件,文字都有許多您需要注意的陷阱。有些可能會導致許多問題,從應用程式中的錯誤到視覺假象甚至受害者!讓我們看看如何避免它們。

背景

文字(又稱字串)幾乎存在於所有軟體專案中,從像 hello-worlds 這樣的單行程式碼到包含數十億行程式碼的企業系統,無論程式語言、平台等如何。文字只是字元序列,所以這不應該是一件複雜的事情,對吧?讓我們看看你會遇到哪些陷阱!

信箱

世界上的一些字母(包括英語)是雙院制的,這意味著它們同時包含大寫和小寫字母。
例如:a 是小寫字符,A 是大寫字符。從一種字母大小寫轉換為另一種字母大小寫是一種很常見的操作。

大小寫可能看起來微不足道——一個字元只是轉換(映射)為另一個字元。如果它不是字母,它甚至可能本身就是一個字符,例如 1 或 + 等等。此外,這種映射總是可以簡單地反轉,例如A->a和a->A。所以,乍看之下一切似乎都很好。好吧,事實並非如此!

大小寫錯誤可能會導致死亡

這不是一個笑話,我們也不是在談論憤怒的語法納粹分子。正如您在本文中所讀到的那樣,外殼故障造成 2 名受害者,並使另外 3 人入獄。

這是怎麼發生的?好吧,在土耳其語(和亞塞拜然語)中,我們有 2 個不同的 i 字母:有點(封閉)和無點(開放)。在英語和其他拉丁字母中,小寫字母總是帶點,而大寫字母則不帶點。一切都在表 1 和線上演示中進行了說明。

表 1. 帶點和不帶點的 i 字母。

Lowercase Uppercase
English i dotted I dotless
Turkish i dotted İ dotted
Turkish ı dotless I dotless

如您所見,大小寫變更結果取決於上下文,而上下文又取決於目前語言。在撰寫供人類使用的文本時,使用適當的語言非常重要。如果你不關心這一點,你的話最終可能會產生與預期不同的意義。

另一方面,機器可讀的文字(如 HTTP 標頭或 JSON 鍵)應該以語言中立的方式處理。否則,您可能會在輸出中得到非 ASCII 字符,這可能會破壞應用程式邏輯。這種情況就發生在 GSON 中,這是一個被數千(甚至數百萬)個專案使用的函式庫。

變音符號的秘密

帶有變音符號的字元可以像 ó 這樣預先組合,或者透過組合像 ó 這樣的標記來創建。閱讀此頁時,它們看起來像是同一個角色。然而,如果查看第二個的十六進制轉儲,或者甚至嘗試以編程方式獲取其長度(如本演示所示),您將看到它由2 個單獨的字符組成:拉丁小寫字母o 和組合的銳音符。同樣,每個 Hangul(韓文字母)音節區塊都可以預先組合或書寫為不同的 jamos 單個字母/字元的組合。

為什麼組合標記如此重要?大多數帶有變音符號的字元有兩種書寫方式(例如波蘭語、匈牙利語或捷克語字母)。這使得排序、搜尋或文字長度測量等操作變得非常重要。通常,為了獲得最佳的使用者體驗,需要將文字進行規範化(轉換為一種規範形式)。否則,當使用者看到多個「不同」的登入名稱或看起來相同的檔案名稱時,他們可能會感到困惑。 Slack 如何處理頻道名稱就是一個很好的例子。它們在通道創建之前就已標準化,因此相同名稱以不同方式書寫的情況不能共存。

有些角色比其他角色更平等

字元等效性有 2 個等級。 規範等價 當字符被假定具有相同的含義和外觀時發生,例如上述 ó 和 ó 僅在(技術)書寫方式上有所不同。另一方面,相容性意味著字元可能看起來不同,但可能具有相同的含義。例如,連字 ffi 與三個不同的字母 ffi 相容,但它們在規範上並不相等。有關 Unicode 規範化的更多資訊可以在標準文件中找到。

雖然每 2 個等級的組合形式和分解形式都是標準化的 - 所以我們總共有 4 種範式 - 標準化並不總是可逆的。例如,埃符號 Å 分解為拉丁大寫字母 A A 加上 ̊ 上方的組合環,再組合回拉丁大寫字母 A 且 Å 上方有環,而不是其起源的埃符號。

組合標準化錯誤導致冒險

共享給定文字的所有應用程式都使用相同的標準化方法也很重要。如果不這樣做,可能會導致細微的錯誤和/甚至無聲的資料遺失。此類錯誤可能很難發現,因為每個應用程式都可以完美運行,至少在單獨運行時是如此。在這種情況下,應用程式通常不會“崩潰”,而只是發送或接收與應有的數據不同的數據,從而導致意想不到的後果。 nettalk 中的這個錯誤就是這樣的一個例子。

上述印刷連字用於改善某些字符的視覺外觀,這些字符彼此相鄰時看起來不太好。大多數用戶不需要擔心連字,因為它們是由軟體(例如)從單個字母自動生成的。 TeX 預設產生連字。然而,此類工具的開發人員必須考慮到,在某些情況下,連字可能不合適並引入錯誤。

看看這個:fi。第二個字母是有點的還是無點的?土耳其語讀者可能會感到困惑。在某些情況下不應使用包含 i 的連字。

我的大寫字母在哪裡?

有些文字(所謂的兩院制)如拉丁文和希臘文包含兩種大小寫的字母。幾乎所有字母都有小寫和大寫。幾乎……但不是全部!
雖然小寫字母集始終存在,但大寫字母集並非如此。那麼,如果存在只有小寫的字符,如果您嘗試將它們轉換為大寫,會發生什麼情況?會不會是一個錯誤導致操作失敗?角色會維持不變嗎?答案不是這樣的!

最引人注目的例子之一是德文升音 s — ß。它是一個小寫字符,當轉換為大寫時,它變成雙 S - SS。這種轉變是不可逆的-SS 變成了 ss。網上看看。 TL;DR Unicode 5.1 引入了 ẞ(拉丁文大寫字母升 S),但就字元映射而言,它通常不會被視為 ß 的大寫字母。它最近(2016 年)作為 SS 的同等有效形式添加到德語正字法規則集中。

許多其他小寫連字沒有對應的預組合大寫形式。完整清單可以在 Unicode 特殊大小寫文件中找到。

雙重或三重問題

缺少一些大寫字符,怎麼辦?連字可以由 2 個甚至 3 個字元組成,因此大寫文字可能比原始小寫文字長 3 倍。當生成的文本長度有限時,這一點非常重要。例如,在頭像或縮寫產生器中,就像 bitrise.io 上的這個錯誤一樣。

神秘的第三種情況

希臘字母表中包含西格瑪字母,大寫形式如下:Σ。它的小寫形式是什麼?嗯,這取決於!通常,它是 σ(非詞尾),但在單字末尾,它是 ς(詞尾)。但是,如果西格瑪是唯一的字母或單字全部大寫,則始終使用非最終版本,即使在最終位置也是如此。請參閱互動範例。

另一個邊緣情況

有波形符 Ĩ 的拉丁文大寫字母 i 的小寫字母是什麼?正如您可能已經猜到的,答案並非那麼微不足道。存在相應的小寫形式。兩種形式都是無點的,但這是完全正常的。如果 i 和 j 附加了一些變音符號,則它們都沒有點。那這裡有什麼問題呢?

除了土耳其語之外,立陶宛語的拼字規則在 I 字母的情況下也很例外。在後者中,點保留在重音符號下方。例如,這意味著前面提到的 Ĩ 在立陶宛語中小寫時會變成 i̇̃。如果你仔細觀察,你會發現有 3 個字元:一個拉丁小寫字母 i,上面是一個組合點,上面是一個組合波浪號。文字長度(再次)增加了3倍。

繼續學習連字和多重圖

如何只用 6 個字元寫出一個由 7 個字母組成的單字?只需使用預先組合的連字和多重字母(二字母、三字母等)!當然,對於連接字母的每種可能的組合,沒有預先組成的字元。然而,現有的可以用來有效地增加文字長度限制。例如,西里西亞語單字 dzbonek(鍋子)由 7 個字母組成,但僅使用 6 個字元即可寫為 dzbonek。網上看看。請注意,dz 是二合字母,而不是連字。

例如,現在您可以發送包含超過 140 個字元的推文訊息!可以在此處找到預先組合的 Unicode 二合字母和連字清單。

鮮為人知的按字母順序排列的方法

字母順序通常是在小學開始時教授的。 A、B、C、D...等到 Z。就像派一樣簡單!

不幸的是,字母順序取決於語言。甚至基本拉丁字母(沒有變音符號)的位置也可能不同。例如,在愛沙尼亞語中,字母 Z 位於 S 和 T 之間。

有變音符號的字母的位置也不是通用的。有幾種可能的方案:

  1. 在對應的基本字母之前,如馬耳他語:W、X、Ż、Z。

  2. 在相應的基本字母之後,如波蘭語:A、Ą、B、C、Ć。

  3. 在字母的結尾,如瑞典語:Z、Å、ä。

  4. 與基本字母位於相同位置(用於整理目的),如匈牙利語:O=Ó。

請注意,同一字母在不同語言中的整理方式可能不同,甚至在同一語言中也可能有所不同,具體取決於上下文! 。例如,在斯洛伐克語中,帶有變音符號的 A 總是位於 A 之後。但是,在德語中,它可能與非變音版本具有相同的值、位於其之後,甚至被視為 A+E。有關在哪些情況下使用哪種方式的更多資訊可以在此處找到。

麵包、收銀機和賭場

需要校對的不僅僅是單個字母。多重圖也可以有自己的規則。在斯洛伐克語中,CH 在 H 和 I 之間進行整理。因此,例如,單字 chlieb(麵包)將在 hodina(一小時)之後進行整理。另一方面,在波蘭語中,二合字母被視為兩個單獨的字母 - C 和 H - 因此沒有特殊的排序規則。在線查看。

匈牙利語甚至有雙合字母,每個合字母都有自己的排序規則。這導致了許多複雜的情況。讓我們考慮一個可能的例子。我們有 SZ 有向圖。它是在 S 之後整理的。它的雙重版本(SZ + SZ)是 SSZ。這意味著 kaszinó(賭場)一詞應該位於 kassza(收銀機)之前。通常 Z 在 S 之後,但這裡我們在第一個單字中有 K A SZ I,在第二個單字中有(相當於)K A SZ SZ。

此外,同一組字母可能是也可能不是(雙)二合字母,這取決於上下文。例如,上述斯洛伐克語 CH 在某些單字中被視為 2 個單獨的字母 C 和 H,例如viachlas(複調音樂)。通常,在匈牙利語中,NNY = NY + NY,就像單字 mennybolt(天堂)一樣。然而,我們還有一個 tizennyolc(十八),其中 NNY = N + NY,因此有一個字母 N 和一個二合字母 NY。

ΤНЅ ІЅ NОТ WНаТ ΥОй ТНІNΚ ІТ IЅ

您可能認為上面的標題僅由簡單的拉丁字母組成。事實上,其中絕大多數是希臘語、西里爾語或亞美尼亞語大寫字母。它們只是一些拉丁字母的同形字。

所以 A(拉丁文大寫 A)與 A(希臘大寫 Alpha)或 А(西里爾大寫 A)不同。為什麼這很重要?由於它們無法區分,因此可用於 IDN 同形異義詞攻擊。例如,僅包含拉丁字母的域bank.com看起來與包含西里爾小A而不是拉丁小A的bаk.com非常相似。此類網域可能用於網路釣魚。

包起來

在某些情況下處理文字可能會很棘手 - 特別是當您在多語言環境中工作時。根據經驗,所有配置都應該適合給定的上下文。例如,在處理使用者可見的文字時應考慮使用者目前的語言,而機器可讀的文字應以語言中立的方式處理(如果不可能,則使用英語)。選定的排序規則設定也應符合實際使用情況。文字應在需要時進行標準化,並且所選的標準化方法應在整個系統中保持一致。
想了解更多邊緣狀況嗎?請繼續關注,第二部分即將推出!

以上是要記住的邊緣情況。部分文字的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板