2010-04-07 50 views
6

我想寫一個基於狀態機的(HTML)解析器,但我懷疑如何實際讀取/使用輸入。我決定將整個輸入加載到一個字符串中,然後像數組一樣處理它,並將其索引保存爲當前解析位置。解析PHP中的多字節字符串

單字節編碼沒有問題,但在多字節編碼中,每個值不代表一個字符,而是一個字符的字節。

例子:

$mb_string = 'žščř'; //4 multi-byte characters in UTF-8 

for($i=0; $i < 4; $i++) 
{ 
    echo $mb_string[$i], PHP_EOL; 
} 

輸出:

Ĺ 
ž 
Ĺ 
Ą 

這意味着在一個循環中我無法通過字符串遍歷檢查單個字符,因爲我從來不知道我是否在一個人物的中間或沒有。

所以問題是:

  • 如何多字節安全的 性能友好的方式讀取一個字符串 單個字符?
  • 與 字符串一起使用是否好主意,因爲它是這個 大小寫中的數組?
  • 你會如何閱讀輸入?

回答

2

http://php.net/mb_string是你要找的

  • 只是mb_substr人物一個接一個
  • 直到PHP6
  • 輸入什麼確切的東西?一般
+2

注意,對於'mb_split'評論部分其中包含許多如何將多字節字符串分解爲字符數組的示例 - 例如http://us2.php.net/manual/en/function.mb-split.php#80046 – Amber 2010-04-07 08:45:32

+0

@Dav I don'我認爲他真的需要一個陣列。 – 2010-04-07 08:47:01

+0

通過輸入我的意思是解析的HTML代碼。也許有完全不同的方式如何使用字符串與我缺少的狀態機:-) ...但mb_substr看起來很好(如果我知道字符串編碼,這是不是很明顯) – 2010-04-07 09:08:21

1
mb_internal_encoding("UTF-8"); 

$mb_string = 'žščř'; 

$l=mb_strlen($mb_string); 

for($i=0;$i<$l;$i++){ 
    print(mb_substr($mb_string,$i,1)."<br/>"); 
} 
0

的常用方法如果不使用mdb_relatedFunctions和多字節編碼字符串,你可以使用,在用於編碼的字節數的倍數讀取標準的子字符串函數。

例如,對於UTF-8編碼(2個字節)的字符串,如果你從字符串需要的第一個字符

$string = 'žščř'; //4 multi-byte characters in UTF-8 

你必須得到$字符串[0]和$字符串[1]值,所以你實際上正在尋找索引0和1之間的子串(對於第一個字符)。

注意,$串[0]或$串[N]將引用第一(多字節串的第N個或字節)

問候,

+0

不知道有多少字節需要讀取?這是一個簡單的例子,但通常我不知道輸入中的字符是什麼(UTF-8字符可以是1-4字節長)。 – 2010-04-07 11:03:28

+0

是的,您必須確定使用了多少個字節,但這是一個答案,可能會給您一些關於使用NON mb_related函數的信息 - 以及操縱多字節字符串。希望你覺得它有用。 – Andreas 2010-04-07 11:20:24

+0

這個答案是誤導性的,因爲它表明所有的UTF-8字符都是2字節長。實際上,字節長度取決於所表示的字符。正如@PetrPeller在上面的註釋中指出的那樣,UTF-8字符可以佔用少至1個字節,或多達4個字節。 – Lee 2014-07-09 18:17:22