├── LICENSE ├── README.md ├── persian_test.go └── persian.go /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 mavi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # persian 2 | [![Go Report Card](https://goreportcard.com/badge/github.com/mavihq/persian)](https://goreportcard.com/report/github.com/mavihq/persian) 3 | [![GoDoc](https://godoc.org/github.com/mavihq/persian?status.svg)](https://godoc.org/github.com/mavihq/persian) 4 | 5 | Some utilities for Persian language in Go (Golang). 6 | 7 | ## Installation 8 | ``` 9 | go get github.com/mavihq/persian 10 | ``` 11 | 12 | ## API 13 | ### .ToPersianDigits 14 | Converts all English digits in the string to Persian digits. 15 | ``` 16 | persian.ToPersianDigits("123salam456") 17 | => "۱۲۳salam۴۵۶" 18 | ``` 19 | 20 | ### .ToPersianDigitsFromInt 21 | Converts integer value to string with Persian digits. 22 | ``` 23 | persian.ToPersianDigitsFromInt(123) 24 | => "۱۲۳" 25 | ``` 26 | 27 | ### .ToEnglishDigits 28 | Converts all Persian digits in the string to English digits. 29 | ``` 30 | persian.ToEnglishDigits("۱۲۳salam۴۵۶") 31 | => "123salam456" 32 | ``` 33 | 34 | ### .OnlyEnglishNumbers 35 | Extracts only English digits from string. 36 | ``` 37 | persian.OnlyEnglishNumbers("123salam۴۵۶") 38 | => "123" 39 | ``` 40 | 41 | ### .OnlyPersianNumbers 42 | Extracts only Persian digits from string. 43 | ``` 44 | persian.OnlyPersianNumbers("123salam۴۵۶") 45 | => "۴۵۶" 46 | ``` 47 | 48 | ### .SwitchToPersianKey 49 | Converts English chars to their equivalent Persian char on keyboard. 50 | ``` 51 | persian.SwitchToPersianKey("sghl o,fd ? o,fl llk,k") 52 | => "سلام خوبی ؟ خوبم ممنون" 53 | ``` 54 | 55 | ### .SwitchToEnglishKey 56 | Converts Persian chars to their equivalent English char on keyboard. 57 | ``` 58 | persian.SwitchToEnglishKey("اثغ صاشفس عح ؟") 59 | => "hey whats up ?" 60 | ``` 61 | 62 | ### .Currency 63 | Formats number to Persian currency style. 64 | ``` 65 | persian.Currency("1234567") 66 | => "۱،۲۳۴،۵۶۷" 67 | ``` 68 | 69 | ### .Toman 70 | Formats number to Persian currency style with تومان postfix. 71 | ``` 72 | persian.Toman("1234567") 73 | => "۱،۲۳۴،۵۶۷ تومان" 74 | ``` 75 | 76 | ### .Rial 77 | Formats number to Persian currency style with ﷼ postfix. 78 | ``` 79 | persian.Rial("1234567") 80 | => "۱،۲۳۴،۵۶۷ ﷼" 81 | ``` 82 | 83 | ### .FixArabic 84 | Used for converting Arabic characters to Persian. 85 | ``` 86 | persian.FixArabic("علي") 87 | => "علی" 88 | ``` 89 | -------------------------------------------------------------------------------- /persian_test.go: -------------------------------------------------------------------------------- 1 | package persian 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func Test_toPersianDigits(t *testing.T) { 10 | str := "123salam456" 11 | assert.Equal(t, "۱۲۳salam۴۵۶", ToPersianDigits(str)) 12 | } 13 | 14 | func Test_toPersianDigitsFromInt(t *testing.T) { 15 | value := 123 16 | assert.Equal(t, "۱۲۳", ToPersianDigitsFromInt(value)) 17 | } 18 | 19 | func Test_toEnglishDigits(t *testing.T) { 20 | str := "۱۲۳salam۴۵۶" 21 | assert.Equal(t, "123salam456", ToEnglishDigits(str)) 22 | } 23 | 24 | func Test_onlyEnglishNumbers(t *testing.T) { 25 | value := "salam123hello456۱۲۳سلام۴۵۶" 26 | assert.Equal(t, "123456", OnlyEnglishNumbers(value)) 27 | } 28 | 29 | func Test_onlyPersianNumbers(t *testing.T) { 30 | value := "salam123hello456۱۲۳سلام۴۵۶" 31 | assert.Equal(t, "۱۲۳۴۵۶", OnlyPersianNumbers(value)) 32 | } 33 | 34 | func Test_switchToPersianKey(t *testing.T) { 35 | value := "sghl o,fd ? o,fl llk,k" 36 | assert.Equal(t, "سلام خوبی ؟ خوبم ممنون", SwitchToPersianKey(value)) 37 | } 38 | 39 | func Test_switchToEnglishKey(t *testing.T) { 40 | value := "اثغ صاشفس عح ؟" 41 | assert.Equal(t, "hey whats up ?", SwitchToEnglishKey(value)) 42 | } 43 | 44 | func Test_Currency(t *testing.T) { 45 | value := "123۴۵۶7" 46 | assert.Equal(t, "۱،۲۳۴،۵۶۷", Currency(value)) 47 | } 48 | 49 | func Test_toman(t *testing.T) { 50 | value := "123۴۵۶7" 51 | assert.Equal(t, "۱،۲۳۴،۵۶۷ تومان", Toman(value)) 52 | } 53 | 54 | func Test_rial(t *testing.T) { 55 | value := "123۴۵۶7" 56 | assert.Equal(t, "۱،۲۳۴،۵۶۷ ﷼", Rial(value)) 57 | } 58 | 59 | func Test_fixArabic(t *testing.T) { 60 | value := "علي‌رضا" 61 | assert.Equal(t, "علی‌رضا", FixArabic(value)) 62 | } 63 | 64 | func Test_checkIsEnglish(t *testing.T) { 65 | value := "علي" 66 | assert.Equal(t, false, CheckIsEnglish(value)) 67 | 68 | value = "ali" 69 | assert.Equal(t, true, CheckIsEnglish(value)) 70 | } 71 | 72 | func Test_onlyPersianAlpha(t *testing.T) { 73 | value := "123456شاهینshaahin" 74 | assert.Equal(t, "شاهین", OnlyPersianAlpha(value)) 75 | } 76 | 77 | func Test_Normalize(t *testing.T) { 78 | anormalValue := "متن نا‌نرمال عربي و فارسی با عددهای ۱ و 1" 79 | normalValue := "متن نا نرمال عربی و فارسی با عددهای ۱ و 1" 80 | assert.Equal(t,normalValue,Normalize(anormalValue)) 81 | } -------------------------------------------------------------------------------- /persian.go: -------------------------------------------------------------------------------- 1 | package persian 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "strings" 7 | ) 8 | 9 | //ToPersianDigits Converts all English digits in the string to Persian digits. 10 | func ToPersianDigits(text string) string { 11 | return strings.NewReplacer( 12 | "0", "۰", 13 | "1", "۱", 14 | "2", "۲", 15 | "3", "۳", 16 | "4", "۴", 17 | "5", "۵", 18 | "6", "۶", 19 | "7", "۷", 20 | "8", "۸", 21 | "9", "۹", 22 | ).Replace(text) 23 | } 24 | 25 | //ToPersianDigitsFromInt Converts integer value to string with Persian digits. 26 | func ToPersianDigitsFromInt(value int) string { 27 | return ToPersianDigits(fmt.Sprintf("%d", value)) 28 | } 29 | 30 | //ToEnglishDigits Converts all Persian digits in the string to English digits. 31 | func ToEnglishDigits(text string) string { 32 | return strings.NewReplacer( 33 | "۰", "0", 34 | "۱", "1", 35 | "۲", "2", 36 | "۳", "3", 37 | "۴", "4", 38 | "۵", "5", 39 | "۶", "6", 40 | "۷", "7", 41 | "۸", "8", 42 | "۹", "9", 43 | // Arabic Number 44 | "٠", "0", 45 | "١", "1", 46 | "٢", "2", 47 | "٣", "3", 48 | "٤", "4", 49 | "٥", "5", 50 | "٦", "6", 51 | "٧", "7", 52 | "٨", "8", 53 | "٩", "9", 54 | ).Replace(text) 55 | } 56 | 57 | //OnlyEnglishNumbers extracts only English digits from string. 58 | func OnlyEnglishNumbers(text string) string { 59 | re := regexp.MustCompile("[^0-9.]") 60 | return re.ReplaceAllLiteralString(text, "") 61 | } 62 | 63 | //OnlyPersianNumbers extracts only Persian digits from string. 64 | func OnlyPersianNumbers(text string) string { 65 | re := regexp.MustCompile("[^۰-۹.]") 66 | return re.ReplaceAllLiteralString(text, "") 67 | } 68 | 69 | //OnlyNumbers extracts only digits from string. 70 | func OnlyNumbers(text string) string { 71 | re := regexp.MustCompile("[^۰-۹0-9.]") 72 | return re.ReplaceAllLiteralString(text, "") 73 | } 74 | 75 | //OnlyPersianAlpha extracts only persian alphabetes from string. 76 | func OnlyPersianAlpha(text string) string { 77 | re := regexp.MustCompile("[^\u0600-\u06FF.]") 78 | return re.ReplaceAllLiteralString(text, "") 79 | } 80 | 81 | //SwitchToPersianKey converts English chars to their equivalent Persian char on keyboard. 82 | func SwitchToPersianKey(text string) string { 83 | return strings.NewReplacer( 84 | "q", "ض", 85 | "w", "ص", 86 | "e", "ث", 87 | "r", "ق", 88 | "t", "ف", 89 | "y", "غ", 90 | "u", "ع", 91 | "i", "ه", 92 | "o", "خ", 93 | "p", "ح", 94 | "\\[", "ج", 95 | "\\]", "چ", 96 | "a", "ش", 97 | "s", "س", 98 | "d", "ی", 99 | "f", "ب", 100 | "g", "ل", 101 | "h", "ا", 102 | "j", "ت", 103 | "k", "ن", 104 | "l", "م", 105 | ";", "ک", 106 | "'", "گ", 107 | "z", "ظ", 108 | "x", "ط", 109 | "c", "ز", 110 | "v", "ر", 111 | "b", "ذ", 112 | "n", "د", 113 | "m", "پ", 114 | ",", "و", 115 | "?", "؟", 116 | ).Replace(text) 117 | } 118 | 119 | //SwitchToEnglishKey converts Persian chars to their equivalent English char on keyboard. 120 | func SwitchToEnglishKey(text string) string { 121 | return strings.NewReplacer( 122 | "ض", "q", 123 | "ص", "w", 124 | "ث", "e", 125 | "ق", "r", 126 | "ف", "t", 127 | "غ", "y", 128 | "ع", "u", 129 | "ه", "i", 130 | "خ", "o", 131 | "ح", "p", 132 | "ج", "\\[", 133 | "چ", "\\]", 134 | "ش", "a", 135 | "س", "s", 136 | "ی", "d", 137 | "ب", "f", 138 | "ل", "g", 139 | "ا", "h", 140 | "ت", "j", 141 | "ن", "k", 142 | "م", "l", 143 | "ک", ";", 144 | "گ", "'", 145 | "ظ", "z", 146 | "ط", "x", 147 | "ز", "c", 148 | "ر", "v", 149 | "ذ", "b", 150 | "د", "n", 151 | "پ", "m", 152 | "و", ",", 153 | "؟", "?", 154 | ).Replace(text) 155 | } 156 | 157 | //FixArabic used for converting Arabic characters to Persian. 158 | func FixArabic(text string) string { 159 | return strings.NewReplacer( 160 | "ي", "ی", 161 | "ك", "ک", 162 | "دِ", "د", 163 | "بِ", "ب", 164 | "زِ", "ز", 165 | "ذِ", "ذ", 166 | "ِشِ", "ش", 167 | "ِسِ", "س", 168 | "ى", "ی", 169 | ).Replace(text) 170 | } 171 | 172 | 173 | //Normalize used for Normalize Persian for sort and equality check. 174 | //TODO: Complete list according to Persian Collation 175 | func Normalize(text string) string { 176 | return strings.NewReplacer( 177 | "ي", "ی", 178 | "ك", "ک", 179 | "دِ", "د", 180 | "بِ", "ب", 181 | "زِ", "ز", 182 | "ذِ", "ذ", 183 | "ِشِ", "ش", 184 | "ِسِ", "س", 185 | "‍", " ", 186 | "‌", " ", 187 | "ى", "ی", 188 | "ٱ","ا" , 189 | "آ","ا" , 190 | "ء","ا" , 191 | "ئ","ی" , 192 | "أ","ا" , 193 | "ة","ه" , 194 | ).Replace(text) 195 | } 196 | 197 | 198 | //Reverse reverses the given string. 199 | func Reverse(s string) string { 200 | runes := []rune(s) 201 | for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { 202 | runes[i], runes[j] = runes[j], runes[i] 203 | } 204 | return string(runes) 205 | } 206 | 207 | // Currency formats number to Persian currency style. 208 | func Currency(amount string) string { 209 | countThrees := 0 210 | out := "" 211 | _amount := []rune(OnlyNumbers(amount)) 212 | for i := len(_amount) - 1; i >= 0; i-- { 213 | if countThrees == 3 { 214 | out += "،" + string(_amount[i]) 215 | countThrees = 1 216 | } else { 217 | out += string(_amount[i]) 218 | countThrees++ 219 | } 220 | } 221 | return ToPersianDigits(Reverse(out)) 222 | } 223 | 224 | // Toman formats number to Persian currency style with تومان postfix. 225 | func Toman(amount string) string { 226 | return Currency(amount) + " تومان" 227 | } 228 | 229 | // Rial formats number to Persian currency style with ﷼ postfix. 230 | func Rial(amount string) string { 231 | return Currency(amount) + " ﷼" 232 | } 233 | 234 | func CheckIsEnglish(text string) bool { 235 | for _, r := range text { 236 | if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') { 237 | return false 238 | } 239 | } 240 | return true 241 | } 242 | --------------------------------------------------------------------------------