2011-04-12 22 views
8

所以我有一個UTF-8編碼的字符串,它可以包含全角漢字,全角假名,半角假名,romaji,數字或卡哇伊日本象徵★或♥。用PHP中的半角假名計算日文多字節字符串的長度

如果我想要的長度,我使用mb_strlen(),它計算每個這些長度爲1。對於大多數目的來說這很好。

但是,我被問過(日本客戶)只計算半角假名爲0.5(用於文本字段的最大長度),因爲顯然這就是日文網站的做法。我這樣做使用mb_strwidth(),其中全寬爲2,半寬爲1,然後我除以2.

但是,此方法也計算romaji字符爲1,所以類似Chocアイス將計爲7 ..那麼我會除以2來說明漢字,我會得到3.5。但我實際上想要5.5(羅馬字+4 + 3的半角假名1.5)。

//編輯: 一些更多的信息:其同時具有充分半應爲全寬度和0.5對半寬度爲1的任何字符(甚至非假名)。例如,像¥、3@(字符都應該是1,但像¥,[email protected](字符都應該是0.5

// EXTRA編輯:像☆和♥符號應爲1,但mb_strwidth/2法返回它們作爲0.5

日本的系統是否有統計字符串長度的標準方式? 還是每個人只是循環通過他們的字符串,並計算不符合標準寬度規則的字符?

+1

我自發的想法是像往常一樣使用'mb_strlen'並減去Unicode代碼點FF61和FF9F之間的字符出現次數。我可能會來解決這一問題成爲一個完整的答案後... – deceze 2011-04-12 09:51:50

回答

0

所以,我找不到答案。

我通過字面迭代和檢查每個字符並手動應用我的客戶要求的計數規則來修復它。

3

一種方法是半角片假名轉換爲全角和從原來的長度減去寬度之差:

$raw = 'Chocアイス'; 
$full = mb_convert_kana($raw, 'K'); 
$len = mb_strlen($raw) - (mb_strwidth($full) - mb_strwidth($raw))/2; 
assert($len === 5.5); 

然而,你肯定你應該考慮基本的拉丁字符爲全角?確實存在基本拉丁字符的全角品種 - 也就是說,應該認爲ChocChoc相同?

通常,「A」和「ア」等字符的寬度爲1,但「A」和「ア」的寬度爲2(這是mb_strwidth的作用)。我會小心翼翼地解決這個問題。


鑑於你的編輯mb_strwidth(或mb_strwidth/2)不正是你想要的。

+0

我真的應該更加明確;但符號(♥☆等)應該是1,並且它們在mb_strwidth/2方法中返回0.5。它的所有非常混亂,但我的問題是真的在尋找什麼「標準規則」是這種類型的東西?或者是我的客戶只是在他走的時候做出來的? (他是一位非常成功和經驗豐富的商人)。 – icchanobot 2011-04-12 12:44:15

+0

那些符號(♥☆)不是全寬度雖然。至於標準規則,[Unicode的TR11](http://unicode.org/reports/tr11/)文檔字符是如何分類爲全或半寬。 – 2011-04-13 08:44:39

+0

嗨,我知道他們沒有根據我的代碼的全角,但我被要求把他們計爲1長度。我的客戶向我保證他的規則是標準的,並且在一個受歡迎的網站(http://www.gnavi.co.jp/)上展示了一些符合他的規則的示例。我只是有點希望有一種比我更安全的方式來編碼他的解釋規則。也許我需要用日語找到計算器。 – icchanobot 2011-04-13 09:57:24

0

看看Perl的Unicode::GCString模塊:它給出了所有Unicode的正確列,包括東亞東西。

這是Unicode::LineBreak的基礎組件,我已經找到了做亞洲腳本的正確文本分割絕對不可缺少的。

正如你可能想像,兩者都日本製造™。 :)