将数字转换为英文和亚洲格式的单词






4.97/5 (22投票s)
将数字转换为可读的单词。
- 下载 NumberToWords.zip - 18.07 KB
- 下载 NumbersToIndonesianWords.zip - 16.21 KB
- 下载 NumberTo_English_US_and_UK_Words.zip - 22.79 KB
介绍
我正在浏览文章,偶然看到一篇关于将数字转换为文字的文章,例如将12转换为Twelve。我想我可以用不同的方式尝试同样的事情。我不是程序员,但我喜欢摆弄代码。
我将/会添加我可能不懂的其他语言。例如,我最近添加的印尼语,我甚至无法发音转换后的单词;但我还是做了这个转换器。重点是,请验证并告知我是否需要任何改进。谢谢。
无论如何,Converter
类允许我们将数字转换为文字。让图说话吧!
背景
在深入研究代码之前,让我们看看数字是如何用文字表示的
英文风格 (美国):
123,123,000 = One hundred twenty three million one hundred twenty three thousand
123,000,000 = One hundred twenty three million
123,000 = One hundred twenty three thousand
南亚风格:
12,12,112 = Twelve lakh twelve thousand one hundred twelve
12,00,000 = Twelve lakh
12,000 = twelve thousand
112 = one hundred twelve

印尼语风格:
123,123,100 = Seratus Dua Puluh Tiga Juta Seratus Dua Puluh Tiga Ribu
123,000,000 = Seratus Dua Puluh Tiga Juta
123,000 = Seratus Dua Puluh Tiga Ribu

代码流程
这两种系统最普遍的共同点是数字本身。1就是one,9就是nine,20就是twenty,这两种语言都一样。 不同之处在于较高数字的组合和读法。为了方便实现,我创建了数组。这些数组是转换的核心。棘手的部分在于找到正确的索引,以便我们可以使用这些数组。
Private SingleDigitStringArray() As String = _
{"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"}
Private DoubleDigitsStringArray() As String = _
{"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}
Private TenthDigitStringArray() As String = _
{"Ten", "Eleven", "Tweleve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", _
"Eighteen", "Nineteen"}
Private HigherDigitEnglishStringArray() As String = _
{"", "", "Hundred", "Thousand", "Million", "Billion", "Trillion", "Quadrillion", "Quintillion"}
Private HigherDigitAsianStringArray() As String = _
{"", "", "Hundred", "Thousand", "Lakh", "Karod", "Arab", "Kharab"}
Private EnglishCodeArray() As String = {"1", "22", "3"}
Private AsianCodeArray() As String = {"1", "22", "3", "4", "42", "5", "52", "6", "62", "7", "72", "8", "82"}
Private IndonesianCodeArray() As String = {"1", "22", "3", "4", "42", "420"}
Private SingleDigitIndonesianArray() As String = {"", "Satu", "Dua", "Tiga", "Empat", "Lima", "Enam", _
"Tujuh", "Delapan", "Sembilan"}
Private DoubleDigitIndonesianArray() As String = {"Puluh", "Belas"}
Private HigherDigitIndonesianStringArray() As String = {"", "", "Ratus", "Ribu", "Juta", "Miliar", "Triliun"}
整个过程基本上是数组操作。主要目标是找到与数字及其位置相对应的正确索引,然后从上述数组中提取相应的单词。
让我们开始吧。 在英文转换方法中,我们从右边开始一次处理3位数字,然后根据需要添加thousand/million,直到完成为止,如下所示:
Do
concatHigherDigitString = False
If i > 3 Then concatHigherDigitString = True 'to suffix the Thousand/Million/Billion type of Word
If newAmount.Length >= 4 Then 'work with 3 right most digits at a time
newAmount = amountString.Substring(amountString.Length - i, 3)
End If
'do the conversion and affix the Thousand/Million/Billion type of word at the end when needed
If concatHigherDigitString AndAlso CInt(newAmount) <> 0 Then
result = ThreeDigitsConverter(CInt(newAmount)) & " " & _
HigherDigitEnglishStringArray(i / 3 + 1) & " " & result
Else
result = ThreeDigitsConverter(CInt(newAmount))
End If
workedStringLength += newAmount.Length
newAmount = amountString.Substring(0, amountString.Length - workedStringLength)
i += 3
Loop Until amountString.Length <= workedStringLength
在这两种方法中,我们首先将给定的数字转换为字符串,然后转换为数组,例如,1234转换为“1234”,然后转换为{1, 2, 3, 4},使用以下简单代码。我相信一定有更好的方法来做到这一点…
'convert numbers to array of each digit
Dim amountArray(amountString.Length - 1) As Integer
For i As Integer = amountArray.Length To 1 Step -1
amountArray(i - 1) = amountString.Substring(i - 1, 1)
Next
现在我们逐位处理,但要向后处理,因为个位数字始终保持在个位。 处理像12这样的数字时会变得有点复杂,因为它不读作onetwo,而是读作Twelve。同样,22不是twotwo,而是Twenty two。同样,10001不是Ten thousand zero hundred one,而是Ten thousand one。牢记所有这些,以下循环将找到正确的索引,然后从单词库(我们之前讨论过的fields数组)中,我们将数字转换为单词。
数字转英文单词的主要方法
与其它方法相比,转换为英文的方法比较直接。没有太多特殊情况,所以找到所需数组的正确索引并不难。
For i As Integer = amountArray.Length To 1 Step -1
j = amountArray.Length - i
digit = amountArray(j)
codeIndex = EnglishCodeArray(i - 1)
higherDigitEnglishString = HigherDigitEnglishStringArray(CInt(codeIndex.Substring(0, 1)) - 1)
If codeIndex = "1" Then 'Number [1 9]
result = result & SingleDigitStringArray(digit)
ElseIf codeIndex.Length = 2 And digit <> 0 Then 'Number in tenth place and skip if digit is 0
If digit = 1 Then 'Number [Eleven, Twelve,...., Nineteen]
Dim suffixDigit As Integer = amountArray(j + 1)
result = result & separator & TenthDigitStringArray(suffixDigit) & " " & higherDigitEnglishString
i -= 1 'Skip the next round as we already looked at it
Else 'Number [tenth] and [20+]
If Me.Style = ConvertStyle.EnglishUK Then
result = result & separator & DoubleDigitsStringArray(digit) & "-" & higherDigitEnglishString
ElseIf Me.Style = ConvertStyle.EnglishUS Then
result = result & separator & DoubleDigitsStringArray(digit) & " " & higherDigitEnglishString
End If
End If
ElseIf digit <> 0 Then 'Standard Number like 100, 1000, 1000000 and skip if digit is 0
If Me.Style = ConvertStyle.EnglishUK Then andSeparator = " and"
result = result & separator & SingleDigitStringArray(digit) & " " & higherDigitEnglishString _
& andSeparator
End If
separator = " "
Next
数字转印尼语单词的主要方法
印尼语风格与英文风格有些相似,但有几个特殊情况使其变得困难。对我来说,最困难的部分是数字以“1”开头的情况。 当数字以1开头时,两个单词会合并成一个,但这不仅仅是简单的拼接。有趣的是,我甚至无法正确发音转换后的单词!
For i As Integer = amountArray.Length To 1 Step -1
j = amountArray.Length - i
digit = amountArray(j)
codeIndex = IndonesianCodeArray(i - 1)
higherDigitIndonesianString = HigherDigitIndonesianStringArray(CInt(codeIndex.Substring(0, 1)) - 1)
If codeIndex = "1" Then 'Number [1, 9]
result = result & separator & SingleDigitIndonesianArray(digit)
ElseIf codeIndex.Length = 2 And digit <> 0 Then 'Number in tenth place and skip if digit is 0
Dim suffixDigit As Integer = amountArray(j + 1)
If digit = 1 And suffixDigit < 2 Then 'Number [Ten and Eleven] 'Sepuluh, Sebelas
result = result & separator & "Se" & DoubleDigitIndonesianArray(suffixDigit).ToLower & " " & _
higherDigitIndonesianString
i -= 1
ElseIf digit = 1 And suffixDigit >= 2 Then 'Number [12, 19]
result = result & separator & SingleDigitIndonesianArray(suffixDigit) & " " & _
DoubleDigitIndonesianArray(1) & " " & higherDigitIndonesianString
i -= 1
ElseIf suffixDigit <> 0 Then 'Numbers like [21, 22,..29,31,32..39,41....99] ' except ?0s, ??0s
result = result & separator & SingleDigitIndonesianArray(digit) & " " & _
DoubleDigitIndonesianArray(0)
Else 'Numbers like [20 30 40...90]
result = result & separator & SingleDigitIndonesianArray(digit) & " " & _
DoubleDigitIndonesianArray(0) & " " & higherDigitIndonesianString
End If
ElseIf digit <> 0 Then 'Standard Number like 100+, 1000+, 1000000+ and skip if digit is 0
If digit = 1 Then 'exactly numbers like 100, 1000, 1000000
result = result & separator & "Se" & higherDigitIndonesianString.ToLower
Else
result = result & separator & SingleDigitIndonesianArray(digit) & " " & higherDigitIndonesianString
End If
End If
separator = " "
Next
在此过程中,单词之间会附加一个或两个空格,因此为了清理,我使用RegEx
如下:
Private Function RemoveSpaces(ByVal word As String) As String
Dim regEx As New System.Text.RegularExpressions.Regex(" ")
Return regEx.Replace(word, " ").Trim
End Function
好了,这将把数字转换为文字!
数字格式化(或分组)
还有一个公共函数FormatNumber
,它基本上调用Converter
类中的私有函数FormatNumberPerLanguage
。这个FormatNumberPerLanguage
函数将根据提供的区域名称进行分组格式化。简单使用CultureInfo
类。
Private Function FormatNumberPerLanguage(ByVal culterInfoName As String)
Dim ci As New System.Globalization.CultureInfo(culterInfoName)
ci.NumberFormat.NumberDecimalDigits = 0
Return Me.Amount.ToString("N", ci)
End Function
使用代码
只需创建一个转换器的新实例,然后传入您想转换的数字和转换风格,然后调用Convert方法。
代码块应设置为“格式化”样式,如下所示:
Dim converter As New Converter(number, converter.ConvertStyle.EnglishUS)
Me.RichTextBox1.Text = converter.Convert
converter = New Converter(number, NumberToWords.Converter.ConvertStyle.Asian)
Me.RichTextBox2.Text = converter.Convert
关注点
这两个数组值得一提
Private EnglishCodeArray() As String = {"1", "22", "3"}
Private AsianCodeArray() As String = {"1", "22", "3", "4", "42", "5", "52", "6", "62", "7", "72", "8", "82"}
Private IndonesianCodeArray() As String = {"1", "22", "3", "4", "42", "420"}
…这两个数组有助于确定一个数字是个位、十位还是其它位置…在上面的数组中,双位数“22”将始终代表10位。“4”代表千,“42”代表万。
我有一种感觉,我还没有进行足够的测试,所以我非常期待您的评论。谢谢!