tft每日頭條

 > 科技

 > 空白隐形字符

空白隐形字符

科技 更新时间:2024-07-06 14:47:03

作為一名程序員,無論是前端開發還是後端開發,都可能和正則表達式打交道,有時候明明肉眼可見是符合正則的,為何總是過不去呢?下面先貼一個例子,最近遇到的坑,有興趣可以先試一下複制到記事本和IDE工具内看下。

空白隐形字符(扒一扒史上最坑的空白字符)1

程序員在線找BUG

如下是一個手機号,我們需要通過正則校驗手機号合法性,看起來是完全符合手機号規則的

‭13666668888‬

不使用複雜的的正則校驗,就校驗數字11位,測試複制和手動輸入的結果:

public static void main(String[] args) { System.out.println(ReUtil.isMatch ("(1){1}[0-9]{10}", "\u202D13666668888\u202C")); System.out.println(ReUtil.isMatch ("(1){1}[0-9]{10}", "13666668888")); }

這是什麼奇奇怪怪的東西,為什麼複制到IDE工具内就多了些奇奇怪怪的,\u202D和\u202C顯然是Unicode編碼,具體不在做多解釋,查閱Unicode編碼範圍可知:

2000-206F:常用标點(General Punctuation)

這是标點範圍内的,又是不可見的标點,一般人很難察覺。

遇到這個問題的場景是:我方使用聯系方式請求第三方接口,報聯系方式格式錯誤,第一反應就是對方接口出問題了,截圖和使用文本文檔複制報文給對方(見下圖),對方也認為是自身問題,因為報文看起來有問題,對方表示他們打出的日志也是這樣,不存在編碼格式不統一問題,直到對方說他手打報文發送就沒問題,我才意識到,是不是有什麼奇奇怪怪的字符在捉妖,畢竟以前遇到過帶空格,帶tab的情況。

空白隐形字符(扒一扒史上最坑的空白字符)2

問題報文

二話不說,報文複制到IDE看一眼,當初查換行和tab就是這樣做的。

代碼正如之前所發的,有兩個Unicode編碼,再次和錄入聯系方式的人員确認:

空白隐形字符(扒一扒史上最坑的空白字符)3

似乎馬上要破案了,聯系方式是對方微信發的,可能是從哪裡複制過來的,那麼,一般聯系會從通訊錄或者其他地方複制,網上一搜,果然水果機是有這種機制的,那麼為何要引入這些Unicode編碼呢?查到有如下說法

在所有主要的Web浏覽器中内存中的字符順序(邏輯)與它們顯示的順序(可視)是不同的。Unicode 定義了它其中每個字符的方向屬性,浏覽器應用的一組規則(通過這個來進行自動判斷文本Unicode方向屬性應該使用哪種方向)在顯示時産生正确的順序由Unicode雙向算法進行描述,也可簡稱為BIDI算法。控制字符,有時候也稱非打印字符,是出現在特定的信息文本中,表示某一控制功能的字符。這類字符并不顯示,隻包含某種特定的功能。

說人話,就是有些場景,數據庫之類的存儲的是左到右,但是顯示不行,據說阿拉伯文相關的環境是右到左的,中文英文是左到右,那麼要做到國際化就要對對應文本進行處理。

日常我們書寫文字會知道,書寫的方向是決定于所書寫的文字,漢字、拉丁文字是從左至右,阿拉伯文、希伯來文則是從右至左。相應的,Unicode 字符在設計時就考慮了不同文字方向性的問題,因此定義了每個 Unicode 字符的方向屬性。

隻定義每個Unicode字符方向還是不足夠的,很多時候需要将整體字符串左右反轉,那麼控制字符就派上用場了。

U 202A: LEFT-TO-RIGHT EMBEDDING (LRE)

U 202B: RIGHT-TO-LEFT EMBEDDING (RLE)

U 202D: LEFT-TO-RIGHT OVERRIDE (LRO)

U 202E: RIGHT-TO-LEFT OVERRIDE (RLO)

U 202C: POP DIRECTIONAL FORMATTING (PDF)

PDF即是終點,水果機使用LRO和PDF即達到了控制效果,我們可以測試下LRO相反的RLO的作用,從override的意思來看,就是覆蓋了原有排版,上代碼測試:

public static void main(String[] args) { System.out.println("13666668888"); System.out.println("\u202D13666668888\u202C"); System.out.println("\u202E13666668888\u202C"); }

13666668888

‭13666668888‬

‮13666668888‬

有興趣的可以複制最後一個到IDE或者文本編輯工具看下效果。

水果機通過控制字符控制了字符的左右方向和排版方向,但是這可苦了我們這些程序員了,一不小心就找不到問題所在了,所以對于此類問題,最好就是前端或者後端做正則校驗或者替換掉有問題的字符,指望系統操作人員去手打,既容易出錯還不方便。相關示例代碼如下:

public static void main(String[] args) { System.out.println("13666668888"); System.out.println("\u202D13666668888\u202C"); System.out.println("\u202E13666668888\u202C".replaceAll("\\p{Cf}","")); }

13666668888

‭13666668888‬

13666668888

可以看到第三個順序展示了,其中\p{Cf}是不顯示的Uniicode的一個總稱,經測試郵箱内的特殊字符、區号或者分機号和電話相連的-是不會被替換的,不過查閱了下有\p{P}的說明,也有參數為C的說明,但是沒Cf的說明,不知道哪位大神可以補充說明下。

以上就是史上最坑空白字符的發現過程和具體用途,有興趣的可以就裡面具體的點再查閱下相關文檔,此處不再叙述。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved