'Android convert Arabic number to English Number
I get the following error from the gps:
Fatal Exception: java.lang.NumberFormatException
Invalid double: "-٣٣٫٩٣٨٧٤"
Now this is from a error that I got from a user via Fabric. It looks like arabic so I'm guessing it only happens if you have the language set to that, or your sim card? Is it possible to force the gps to send characters in the 0-9 range? Or can I somehow fix this?
Solution 1:[1]
More generic solution using Character.getNumericValue(char)
static String replaceNonstandardDigits(String input) {
if (input == null || input.isEmpty()) {
return input;
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (isNonstandardDigit(ch)) {
int numericValue = Character.getNumericValue(ch);
if (numericValue >= 0) {
builder.append(numericValue);
}
} else {
builder.append(ch);
}
}
return builder.toString();
}
private static boolean isNonstandardDigit(char ch) {
return Character.isDigit(ch) && !(ch >= '0' && ch <= '9');
}
Solution 2:[2]
A modified generic solution
fun convertArabic(arabicStr: String): String? {
val chArr = arabicStr.toCharArray()
val sb = StringBuilder()
for (ch in chArr) {
if (Character.isDigit(ch)) {
sb.append(Character.getNumericValue(ch))
}else if (ch == '?'){
sb.append(".")
}
else {
sb.append(ch)
}
}
return sb.toString()
}
The second branch is necessary as double numbers has this character as dot separator '?'
Solution 3:[3]
Kotlin developers:
fun ArabicToEnglish(str: String):String {
var result = ""
var en = '0'
for (ch in str) {
en = ch
when (ch) {
'?' -> en = '0'
'?' -> en = '1'
'?' -> en = '2'
'?' -> en = '3'
'?' -> en = '4'
'?' -> en = '5'
'?' -> en = '6'
'?' -> en = '7'
'?' -> en = '8'
'?' -> en = '9'
}
result = "${result}$en"
}
return result
}
Solution 4:[4]
This is my code to convert an English number to an Arabic one, the solution could be optimized, modify it according to your needs, it works for all numbers.
fun englishNumberToArabicNumber(number: Int): String {
val arabicNumber = mutableListOf<String>()
for (element in number.toString()) {
when (element) {
'1' -> arabicNumber.add("?")
'2' -> arabicNumber.add("?")
'3' -> arabicNumber.add("?")
'4' -> arabicNumber.add("?")
'5' -> arabicNumber.add("?")
'6' -> arabicNumber.add("?")
'7' -> arabicNumber.add("?")
'8' -> arabicNumber.add("?")
'9' -> arabicNumber.add("?")
else -> arabicNumber.add("?")
}
}
return arabicNumber.toString()
.replace("[", "")
.replace("]", "")
.replace(",", "")
.replace(" ", "")
}
Solution 5:[5]
Simple answer
NumberFormat.getInstance(Locale.getDefault()).format(123)
If you want to set for a particular language
NumberFormat.getInstance(Locale.forLanguageTag("ar"))
NumberFormat.getInstance(Locale.ENGLISH)
Solution 6:[6]
Here is another "manual" solution in Kotlin. It might not be the best solution performance-wise.
val number: Double = "??????????".parseToDouble()
/**
* Parses any valid number string to a [Double].
* The number can be in Persian/Urdu, Eastern Arabic, or Westerns Arabic numerals.
* The number can have thousands separators (Persian/Urdu/Eastern Arabic `?` or English `,` or others).
* The number can be a mix of the above; for example,
* it can have Persian numerals, [thin space](https://en.wikipedia.org/wiki/Thin_space) `?` as thousands separator, and point `.` as decimal separator.
*
* Also see [this Wikipedia article](https://en.wikipedia.org/wiki/Arabic_script_in_Unicode)
*/
fun String.parseToDouble() = this
.normalizeDigits()
.normalizeDecimalSeparator()
.removeOptionalCharacters()
.toDouble()
/**
* Converts [Persian/Urdu and Eastern Arabic digits](https://en.wikipedia.org/wiki/Eastern_Arabic_numerals#Numerals) to Western Arabic digits
*/
fun String.normalizeDigits() = this
// Replace Persian/Urdu numerals
.replace(Regex("[?-?]")) { match -> (match.value.single() - '?').toString() }
// Replace Eastern Arabic numerals
.replace(Regex("[?-?]")) { match -> (match.value.single() - '?').toString() }
/**
* Converts [Persian/Urdu/Eastern Arabic decimal separator](https://en.wikipedia.org/wiki/Decimal_separator#Other_numeral_systems) `?` or slash `/` (invalid and non-standard) to `.` (decimal separator in English)
*/
fun String.normalizeDecimalSeparator() = this.replace('?', '.').replace('/', '.')
/**
* Removes everything except Western Arabic digits and point `.` (for example, thousands separators)
*/
fun String.removeOptionalCharacters() = this.replace(Regex("[^\\d.]"), "")
See this Wikipedia article for difference between numerals.
Solution 7:[7]
Only 6 lines in Kotlin
val ar = "-????????"
val en = ar.map {
if (it.code in 1632..1641) (it.code - 1632 + 48).toChar()
else it
}.joinToString("")
Here, 1632 & 1641 are the values of 0(zero) & 9(nine) respectively in Arabic.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Flovettee |
| Solution 2 | Mahmoud Mabrok |
| Solution 3 | Parisa Baastani |
| Solution 4 | Younes Belouche |
| Solution 5 | Suraj Rao |
| Solution 6 | |
| Solution 7 | philoopher97 |
