2014-12-23 59 views
1

我試圖寫一個函數如何檢索[]符文的第一個「完整」字符?

func Anonymize(name string) string 

是匿名的名字。以下是對輸入和輸出的一些例子,所以你得到的是什麼是應該做的一個想法:

Müller → M. 
von der Linden → v. d. L. 
Meyer-Schulze → M.-S. 

這個功能應該與由出任意字符名稱的工作。儘管實現這一功能我有以下問題:一[]runestring,我如何找出有多少符文要好好得到一個完整的角色,完成在這個意義上,所有的調節器和組合口音相應

鑑於對角色也採取了。例如,如果輸入是[]rune{0x0041, 0x0308, 0x0066, 0x0067}(對應於字符串ÄBC,其中Ä表示爲A和組合結構的組合),該函數應返回2,因爲前兩個符文產生第一個字符Ä。如果我拿了第一個符文,我會得到A,這是不正確的。

我需要這個問題的答案,因爲我想匿名的名字可能以重音字符開頭,我不想刪除口音。

回答

2

你可以試試下面的函數(由 「Go language string length」 的啓發):

func FirstGraphemeLen(str string) int { 
    re := regexp.MustCompile("\\PM\\pM*|.") 
    return len([]rune(re.FindAllString(str, -1)[0])) 
} 

this example

r := []rune{0x0041, 0x0308, 0x0066, 0x0041, 0x0308, 0x0067} 
s := string(r) 
fmt.Println(s, len(r), FirstGraphemeLen(s)) 

輸出:

ÄfÄg 6 2 

該字符串可能會使用6個符文,但其第一個字形使用2.


OP FUZxxl使用另一種方法,使用unicode.IsMark(r)

IsMark報告的符文是否爲標記字符(類別M)。

源(來自FUZxxl的play.golang.org)包括:

// take one character including all modifiers from the last name 
r, _, err := ln.ReadRune() 
if err != nil { 
    /* ... */ 
} 

aln = append(aln, r) 

for { 
    r, _, err = ln.ReadRune() 
    if err != nil { 
     goto done 
    } 

    if !unicode.IsMark(r) { 
     break 
    } 

    aln = append(aln, r) 
} 

aln = append(aln, '.') 
/* ... */ 
+0

這幫助,雖然我沒有在實際代碼中使用正則表達式。這是[我是如何做到的](http://play.golang.org/p/yjzmGsqltG)。 – fuz

+0

@FUZxxl IsMark的確如此。爲了提高可見性,我在答案中包含了解決方案。 – VonC

+0

謝謝你提供這個答案。 – fuz

相關問題