2011-08-17 63 views
5

我在我正在定製的腳本中找到了這個正則表達式。有人能告訴我它在做什麼嗎?這個正則表達式在做什麼?

function test($text) { 
    $regex = '/([\x00-\x7F] | [\xC0-\xDF][\x80-\xBF] | [\xE0-\xEF][\x80-\xBF]{2} | [\xF0-\xF7][\x80-\xBF]{3}) | ./x'; 
    return preg_replace($regex, '$1', $text); 
} 
+1

哪部分你不明白?什麼是上下文? –

+0

wooooah !! ,你的正則表達式給了我起雞皮疙瘩:-) –

回答

2

裏面捕獲組有四個選項:

  1. [\x00-\x7F]
  2. [\xC0-\xDF][\x80-\xBF]
  3. [\xE0-\xEF][\x80-\xBF]{2}
  4. [\xF0-\xF7][\x80-\xBF]{3}

如果這些模式在給定位置都不匹配,則任何字符都將與捕獲組之外的.相匹配。

preg_replace調用將遍歷$text查找所有不重疊的匹配,用捕獲的任何匹配替換每個匹配。

有兩種可能性這裏,或者是整個比賽是捕獲組內,從而替換不改變$text.在端部相匹配的單個字符,並且字符從$text除去。

下面是一些基本的例子:

  • 如果範圍\xF8-\xFF一個字符出現在文本中,它總是會被刪除
  • \xC0-\xDF一個字符將被刪除,除非\x80-\xBF後面跟一個字符
  • 除非隨後兩個字符中\x80-\xBF
  • 甲字在\xF0-\xF7 WIL在\xE0-\xEF一個字符將被刪除升除非在\x80-\xBF
  • \x80-\xBF一個字符將被刪除,除非它是作爲對上述情況
1

目的似乎是「乾淨」的一個的一部分匹配,隨後三個字符被去除UTF- 8編碼文本。捕獲組中的部分,

([\x00-\x7F] | [\xC0-\xDF][\x80-\xBF] | [\xE0-\xEF][\x80-\xBF]{2} | [\xF0-\xF7][\x80-\xBF]{3}) 

...大致相匹配的有效UTF-8字節序列,其可以是一到四個字節長。第一個字節的值決定了該特定字節序列應該有多長。

由於替換簡單,'$1',有效的字節序列將被直接插入到輸出中。任何與該部分不匹配的字節將被該點(.)匹配,並被有效地移除。

瞭解這項技術最重要的是你永遠不必使用它。如果您在UTF-8編碼文本中發現無效的UTF-8字節序列,則意味着兩件事之一:它不是真正的UTF-8,或者它已被破壞。而不是「清理」它,你應該找出它是如何變髒並修復問題。

+0

雖然你是正確的,但它在到達PHP之前並不總是可以清理你的輸入。當我使用外部工具處理作爲JSON字符串返回的Excel文件時,我剛剛遇到了上述問題解決的問題。 作爲非UTF字符的PHP JSON解碼器barfs,他們需要被剝離出來,上面的代碼做得非常好。 – Danack