TextView Numbers shown in English in Persian font - java

I am loading a string which contains some number (all in Persian) into an android TextView. Everything was fine until I changed my custom font, numbers of text shown as English number.
Expected : ۱۲۳۴
Received : 1234
I know that my new font support Persian number. When I change the number locale using code below the number shown correctly.
NumberFormat numberFormat = NumberFormat.getInstance(new Locale("fa", "IR"));
String newNumber = numberFormat.format(number);
The problem is I have a string and it's hard to find the numeric part and change it. also my previous font works fine and I can't understand what's the problem with this font.
Any Idea how to globally solve this problem for all textview, or at least for a string?

Try to use this method:
private String setPersianNumbers(String str) {
return str
.replace("0", "۰")
.replace("1", "۱")
.replace("2", "۲")
.replace("3", "۳")
.replace("4", "۴")
.replace("5", "۵")
.replace("6", "۶")
.replace("7", "۷")
.replace("8", "۸")
.replace("9", "۹");
}

You can use this
String NumberString = String.format("%d", NumberInteger);
123 will become ١٢٣

Use this code for show Hegira date in Persian number:
String farsiDate = "1398/11/3";
farsiDate = farsiDate
.replace('0', '٠')
.replace('1', '١')
.replace('2', '٢')
.replace('3', '٣')
.replace('4', '٤')
.replace('5', '٥')
.replace('6', '٦')
.replace('7', '٧')
.replace('8', '٨')
.replace('9', '٩');
dateText.setText(farsiDate);

You'll have to translate it yourself. TextFormat does not automatically translate from arabic digits to any other language's, because that's actually not what people usually want. Each of those digits have their own character codes, a simple walk of the string and replacing them with the appropriate persian code would be sufficient.

private static String[] persianNumbers = new String[]{ "۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹" };
public static String PerisanNumber(String text) {
if (text.length() == 0) {
return "";
}
String out = "";
int length = text.length();
for (int i = 0; i < length; i++) {
char c = text.charAt(i);
if ('0' <= c && c <= '9') {
int number = Integer.parseInt(String.valueOf(c));
out += persianNumbers[number];
} else if (c == '٫') {
out += '،';
} else {
out += c;
}
}
return out;
}}
and after that u can use it like below vlock
TextView textView = findViewById(R.id.text_view);
textView.setText(PersianDigitConverter.PerisanNumber("این یک نمونه است ۱۲ "));

In JS, you can use the function below:
function toPersianDigits(inputValue: any) {
let value = `${inputValue}`;
const charCodeZero = '۰'.charCodeAt(0);
return String(value).replace(/[0-9]/g, w =>
String.fromCharCode(w.charCodeAt(0) + charCodeZero - 48),
);
}
export {toPersianDigits};

Related

finding the number of open closed html tags in a string

I trying to figure out the best way to find the number of valid HTML tags in a string.
The assumption is that the tag is valid only if it has an opening and closing tag
this is an example of a test case
INPUT
"html": "<html><head></head><body><div><div></div></div>"
Output
"validTags":3
If you need to parse HTML
Do not do it yourself. There is no need to reinvent the wheel. There is a plethora of libraries for parsing HTML. Use the proper tool for the proper job.
Concentrate your efforts on the rest of your project. Sure, you could implement your own function that parses a string, looks for < and >, and acts appropriately. But HTML might be slightly more complex than you imagine, or you might end up needing more HTML parsing than just counting tags.
Maybe in the future you'llwant to count <br/> and <br /> as well. Or you'll want to find the depth of the HTML tree.
Maybe your homemade code doesn't account for all possible combinations of escaping characters, nested tags, etc. How many correct tags are there in the string:
<a><b><c><d e><f g="<h></h>"><i j="<k>" l="</k>"></i></f></e d></b></c></ a >
In a comment, user dbl linked to a similar question with links to libraries: How to validate HTML from java ?
If you want to count open-closed tag pairs as a learning project
Here is a proposed algorithm in pseudocode, as a recursive function:
function count_tags(s):
tag, remainder = find_next_tag(s)
found, inside, after = find_closing_tag(tag, remainder)
if (found)
return 1 + count_tags(inside) + count_tags(after)
else
return count_tags(inside)
Examples
on the string hello <a>world<c></c></a><b></b>, we will get:
tag = "<a>"
remainder = "world<c></c></a><b></b>"
found = true
inside = "world<c></c>"
after = "<b></b>"
return 1 + count_tags("world<c></c>") + count_tags("<b></b>")
on the string <html><head></head>:
tag = "<html>"
remainder = "<head></head>"
found = false
inside = "<head></head>"
after = ""
return count_tags("<head></head>")
on the string <a><b></a></b>:
tag = "<a>"
remainder = "<b></a></b>"
found = true
inside = "<b>"
after = "</b>"
return 1 + count_tags("<b>") + count_tags("</b>")
I wrote a function that would do exactly this.
static int checkValidTags(String html,String[] openTags, String[] closeTags) {
//openTags and closeTags must have the same length;
//This function keeps track of all opening tags.
//and removes the opening and closing tags if the tag is closed correctly
//It can even detect when there are labels added to the tags.
HashMap<Character,Integer> open = new HashMap<>();
HashMap<Character,Integer> close = new HashMap<>();
//Use a start character, this is 1 because 0 would be a string terminator.
int startChar = 1;
for(int i = 0; i < openTags.length; i++) {
open.put((char)startChar, i);
close.put((char)(startChar+1), i);
html = html.replaceAll(openTags[i],""+ (char)startChar);
html = html.replaceAll(closeTags[i],""+(char)(startChar+1));
startChar+=2;
}
List<List<Integer>> startIndexes = new ArrayList<>();
int validLabels = 0;
for(int i = 0; i < openTags.length; i++) {
startIndexes.add(new ArrayList<>());
}
for(int i = 0; i < html.length(); i++) {
char c = html.charAt(i);
if(open.get(c)!=null) {
startIndexes.get(open.get(c)).add(0,i);
}
if(close.get(c)!=null&&!startIndexes.get(close.get(c)).isEmpty()) {
String closed = html.substring(startIndexes.get(close.get(c)).get(0),i);
for(int k = 0; k < startIndexes.size(); k++) {
if(!startIndexes.get(k).isEmpty()) {
int p = startIndexes.get(k).get(0);
if(p > startIndexes.get(close.get(c)).get(0)) {
startIndexes.get(k).remove(0);
}
}
}
startIndexes.get(close.get(c)).remove(0);
html.replace(closed, "");
validLabels++;
}
}
return validLabels;
}
And to use it in your example you would do like this:
String html = "<html><head></head><body><div><div></div></div>";
int validTags = checkValidTags(html,new String[] {
//Add here all the tags you are looking for.
//Remove the trailing '>' so it can detect extra tags appended to it
"<html","<head","<body","<div"
}, new String[]{
"</html>","</head>","</body>","</div>"
});
System.out.println(validTags);
Output:
3

Converting from base X to base Y in JAVA is returning different characters than the same function in PHP

I've created a method in JAVA in order to do the same thing of an existing PHP function, that is: convert an arbitrarily large number from any base to any base.
The java method is working fine and I can convert numbers from one base to another and then convert it back, but the resulted strings are different from the PHP function. This is a problem to me, because I want to convert a number in PHP and then convert it back in JAVA.
For example, lets convert the number 998765;43210;9999;2 from Base11 with alphabet 0123456789; to Base21 with alphabet 0123456789ABCDEFGHIJK in PHP and JAVA:
Result of the example in PHP:
convBase("998765;43210;9999;2", "0123456789;", "0123456789ABCDEFGHIJK") = "GJK7K6B2KKGKK96"
Result of the example in JAVA:
convBase("998765;43210;9999;2", "0123456789;", "0123456789ABCDEFGHIJK") = "1B0EJAJ0IG3DABI"
I would like the results to be the same, so I could convert a number in PHP and convert it back in JAVA.
I think that the problem can be character encoding, but I don't know how to solve it.
PHP function and test:
<?php
function convBase($numberInput, $fromBaseInput, $toBaseInput)
{
if ($fromBaseInput==$toBaseInput) return $numberInput;
$fromBase = str_split($fromBaseInput,1);
$toBase = str_split($toBaseInput,1);
$number = str_split($numberInput,1);
$fromLen=strlen($fromBaseInput);
$toLen=strlen($toBaseInput);
$numberLen=strlen($numberInput);
$retval='';
if ($toBaseInput == '0123456789')
{
$retval=0;
for ($i = 1;$i <= $numberLen; $i++)
$retval = bcadd($retval, bcmul(array_search($number[$i-1], $fromBase),bcpow($fromLen,$numberLen-$i)));
return $retval;
}
if ($fromBaseInput != '0123456789')
$base10=convBase($numberInput, $fromBaseInput, '0123456789');
else
$base10 = $numberInput;
if ($base10<strlen($toBaseInput))
return $toBase[$base10];
while($base10 != '0')
{
$retval = $toBase[bcmod($base10,$toLen)].$retval;
$base10 = bcdiv($base10,$toLen,0);
}
return $retval;
}
header('Content-Type: text/html; charset=utf-8');
$number = "998765;43210;9999;2";
$fromBase = "0123456789;";
$toBase = "0123456789ABCDEFGHIJK";
$converted = convBase($number, $fromBase, $toBase);
$back = convBase($converted, $toBase, $fromBase);
echo "Number: ".$number."<br>";
echo "Converted: ".$converted."<br>";
echo "Back: ".$back."<br>";
?>
JAVA method and test:
import java.math.BigInteger;
public class ConvBase{
public static String convBase(String number, String fromBaseInput, String toBaseInput){
if (fromBaseInput.equals(toBaseInput))
return number;
BigInteger fromLen = new BigInteger(""+fromBaseInput.length());
BigInteger toLen = new BigInteger(""+toBaseInput.length());
BigInteger numberLen = new BigInteger(""+number.length());
if(toBaseInput.equals("0123456789")){
BigInteger retval = BigInteger.ZERO;
for(int i=1; i<=number.length(); i++){
retval = retval.add(
new BigInteger(""+fromBaseInput.indexOf(number.charAt(i-1))).multiply(
fromLen.pow(numberLen.subtract(new BigInteger(""+i)).intValue())
//pow(fromLen, numberLen.subtract(new BigInteger(""+i)))
)
);
}
return ""+retval;
}
String base10 = fromBaseInput.equals("0123456789") ? number : convBase(number, fromBaseInput, "0123456789");
if(new BigInteger(base10).compareTo(toLen) < 0)
return ""+toBaseInput.charAt(Integer.parseInt(base10));
String retVal = "";
BigInteger base10bigInt = new BigInteger(base10);
while(!base10bigInt.equals(BigInteger.ZERO)){
retVal = toBaseInput.charAt(base10bigInt.mod(toLen).intValue()) + retVal;
base10bigInt = base10bigInt.divide(toLen);
}
return ""+retVal;
}
public static void main(String[] args) {
String number = "98765;43210;9999;2";
String fromBase = "0123456789;";
String toBase = "0123456789ABCDEFGHIJK";
String converted = ConvBase.convBase(number, fromBase, toBase);
String back = ConvBase.convBase(converted, toBase, fromBase);
System.out.println("Number = "+number);
System.out.println("Converted = "+converted);
System.out.println("Back = "+back);
System.exit(0);
}
}
There is a typo in your test case. Both programs seem to be correct, or at least consistent.
Your Java variant converts "98765;43210;9999;2" while your PHP program converts "998765;43210;9999;2". Note the two nines at the beginning. When I changed the number I got the following output:
Number = 998765;43210;9999;2
Converted = GJK7K6B2KKGKK96
Back = 998765;43210;9999;2
which is consistent with the output of the PHP version.

How to remove country code , When Pick Phone Number from contacts

I have doubt in that section. How to Remove country code, when I pick phone number from contact list?
Ex: +91 999999999 instead of 9999999999 or +020 9696854549 instead of 9696854549 Can any one know the answer about my question. please give solution to this problem
I attached my code and image here.
private void contactPicked(Intent data) {
Cursor cursor = null;
try {
String phoneNo = null ;
// getData() method will have the Content Uri of the selected contact
Uri uri = data.getData();
//Query the content uri
cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
// column index of the phone number
int phoneIndex =cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER
phoneNo = cursor.getString(phoneIndex);
String phoneNumber = phoneNo.replaceAll(" ","");
mobile_et.setText(phoneNumber);
} catch (Exception e) {
e.printStackTrace();
}
}
You can use startsWith()
This method has two variants and tests if a string starts with the
specified prefix beginning a specified index or by default at the
beginning.
if(phoneNumber.startsWith("+"))
{
if(phoneNumber.length()==13)
{
String str_getMOBILE=phoneNumber.substring(3);
mobile_et.setText(str_getMOBILE);
}
else if(phoneNumber.length()==14)
{
String str_getMOBILE=phoneNumber.substring(4);
mobile_et.setText(str_getMOBILE);
}
}
else
{
mobile_et.setText(phoneNumber);
}
My English is poor, but I will try my best to answer your question.
First of all , add this line to your build.gradle
compile 'com.googlecode.libphonenumber:libphonenumber:8.7.0'
And below is a sample write by kotlin
fun deleteCountry(phone: String) : String{
val phoneInstance = PhoneNumberUtil.getInstance()
try {
val phoneNumber = phoneInstance.parse(phone, null)
return phoneNumber?.nationalNumber?.toString()?:phone
}catch (_ : Exception) {
}
return phone
}
If phone number not start with a '+' followed by the country calling code then you should pass region information, for example:
val phoneNumber = phoneInstance.parse(phone, "CN")
Try this....
if(number.length()>10)
{
int startidx=number.length()-10;
String getnumber=number.substring(startidx,number.length());
etEmerNumber.setText(getnumber);
}
else
{
etEmerNumber.setText(number);
}
I am just simply extending the answer that If you don't want to use any library then you can do it in this way. In order to match any prefix and since some countries could share partially the same prefix (for example 91 and 91-721), you add all possibilities to the regex in descending order and size.
Follow this Code:
public static String PhoneNumberWithoutCountryCode(String phoneNumberWithCountryCode){//+91 7698989898
Pattern compile = Pattern.compile("\\+(?:998|996|995|994|993|992|977|976|975|974|973|972|971|970|968|967|966|965|964|963|962|961|960|886|880|856|855|853|852|850|692|691|690|689|688|687|686|685|683|682|681|680|679|678|677|676|675|674|673|672|670|599|598|597|595|593|592|591|590|509|508|507|506|505|504|503|502|501|500|423|421|420|389|387|386|385|383|382|381|380|379|378|377|376|375|374|373|372|371|370|359|358|357|356|355|354|353|352|351|350|299|298|297|291|290|269|268|267|266|265|264|263|262|261|260|258|257|256|255|254|253|252|251|250|249|248|246|245|244|243|242|241|240|239|238|237|236|235|234|233|232|231|230|229|228|227|226|225|224|223|222|221|220|218|216|213|212|211|98|95|94|93|92|91|90|86|84|82|81|66|65|64|63|62|61|60|58|57|56|55|54|53|52|51|49|48|47|46|45|44\\D?1624|44\\D?1534|44\\D?1481|44|43|41|40|39|36|34|33|32|31|30|27|20|7|1\\D?939|1\\D?876|1\\D?869|1\\D?868|1\\D?849|1\\D?829|1\\D?809|1\\D?787|1\\D?784|1\\D?767|1\\D?758|1\\D?721|1\\D?684|1\\D?671|1\\D?670|1\\D?664|1\\D?649|1\\D?473|1\\D?441|1\\D?345|1\\D?340|1\\D?284|1\\D?268|1\\D?264|1\\D?246|1\\D?242|1)\\D?");
String number = phoneNumberWithCountryCode.replaceAll(compile.pattern(), "");
//Log.e(tag, "number::_>" + number);//OutPut::7698989898
return number;
}
It will work for all instances. You need not care about how much digit the country code is
String get_Mo = phoneNumber.substring(phoneNumber.lastIndexOf(' ')+1));
If you can use a library, this might help you:
Gradle:
repositories {
mavenCentral()
}
dependencies {
implementation 'io.michaelrocks:libphonenumber-android:8.12.51'
}
Java:
String getPhoneNummberWithoutCountryCode(String phoneNo)
{
PhoneNumberUtil phoneInstance = PhoneNumberUtil.createInstance(this.getContext());
Phonenumber.PhoneNumber phoneNumber = phoneInstance.parse(phoneNo, null);
String nationalSignificantNumber = phoneInstance.getNationalSignificantNumber(phoneNumber);
return nationalSignificantNumber;
}
nationalSignificantNumber is the required phone number
use this function hope it will help you out:
public String phoeNumberWithOutCountryCode(String phoneNumberWithCountryCode) {
Pattern complie = Pattern.compile(" ");
String[] phonenUmber = complie.split(phoneNumberWithCountryCode);
Log.e("number is", phonenUmber[1]);
return phonenUmber[1];
}
String Trimmed = s.toString().trim();
if(Trimmed.length() > 10){
char[] number = Trimmed.toCharArray();
int extra;
int dif = Trimmed.length() - 10 ;
for(int i = dif; i < Trimmed.length() ; i++){
extra = i-dif;
number[extra] = number[i];
}
for (int i = 10 ; i < Trimmed.length() ; i++){
number[i]=' ';
}
String finalNumber = String.valueOf(number);
MobileNumberET.setText(finalNumber.trim());
}
//paste this in your text change listener
Use a library
https://groups.google.com/forum/?hl=en&fromgroups#!forum/libphonenumber-discuss
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
// phone must begin with '+'
PhoneNumber numberProto = phoneUtil.parse(phone, "");
int countryCode = numberProto.getCountryCode();
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
If you'd like to perform some extra function on a particular Sim on the mobile you can use some of the many methods below.
Might not be a perfect solution but, I'll try my best.
First get the country code programmatically :
TelephonyManager tm = (TelephonyManager)
this.getSystemService(Context.TELEPHONY_SERVICE);
//get the country iso from sim e.g US, NG, FR etc
String countryIso = tm.getSimCountryIso().toUpperCase():
//get countrycode from refegion returns the code e.g +123, +1, +23 etc.
Int countryCode =
phoneNumberUtil.getInstance().getCountryCodeForRegion(countryIso);
Then you can remove it using your preferred way likeString PhoneNumber = phoneNo.replaceAll("countryCode ", "" );
First of all, make sure your given phone number should be in a Normalized format
like
+921234567
then use the libphonenumber google library, so, in build.gradle add this
implementation 'com.googlecode.libphonenumber:libphonenumber:8.13.4'
then follow the below code:
val phoneUtil = PhoneNumberUtil.getInstance()
try {
val phoneNumberProto: Phonenumber.PhoneNumber = phoneUtil.parse(number, null)
val numberWithoutCountryCode = phoneUtil.getNationalSignificantNumber(phoneNumberProto)
Log.d(Constant.LOG_APP_DEBUG, "PhoneNumber: $numberWithoutCountryCode")
} catch (e: NumberParseException) {
Log.d(Constant.LOG_APP_DEBUG, "NumberParseException was thrown: $e")
}

Check if String token contains string char and String number value

1)I need to check if String contains a String characters what will be the corect way how to do it ?
2) Are some ways how to corectly transform String to number and then compare theese two number s? Like String = "House":1234 is equal to "House":1234 but no to "house":123
Priview:
String token ="123"; False
String token = "ā123"; or other characters True utc.
if(isChars(token)){
Long value = toLong(token);
}
THANKS!
//EDIT
public BigDecimal eval() {
Stack<BigDecimal> stack = new Stack<BigDecimal>();
for (String token : getRPN()) {
if (operators.containsKey(token)) {
BigDecimal v1 = stack.pop();
BigDecimal v2 = stack.pop();
stack.push(operators.get(token).eval(v2, v1));
} else if (variables.containsKey(token)) {
stack.push(variables.get(token).round(mc));
} else if (functions.containsKey(token.toUpperCase())) {
Function f = functions.get(token.toUpperCase());
ArrayList<BigDecimal> p = new ArrayList<BigDecimal>(f.getNumParams());
for (int i = 0; i < f.numParams; i++) {
p.add(0, stack.pop());
}
BigDecimal fResult = f.eval(p);
stack.push(fResult);
} else if (isDate(token)) {
Long date = null;
try {
date = SU.sdf.parse(token).getTime();
} catch (ParseException e) {/* IGNORE! */
}
// mylog.pl("LONG DATE : "+new BigDecimal(date, mc));
stack.push(new BigDecimal(date, mc));
}//TODO HERE
else if (isChar(token)){
Long cha = toLong(token);
stack.push(new BigDecimal(cha, mc));
//TODO ENDS HERE
}
else {
// mylog.pl("Token : "+ token);
stack.push(new BigDecimal(token, mc));
}
}
return stack.pop().stripTrailingZeros();
}
Another way for determing whether string contains any chars is nice class StringUtils from apache-commons-lang library.
It contains several methods for analyzing string's contents. It seems that in your case you can use StringUtils.isAlphanumeric(CharSequence cs) or negation of StringUtils.isNumeric(CharSequence cs)'s result.
What about second part of your question, so I do not see here necessety of extracting numbers from string. You can compare strings "House":1234 and "house":123 using standard String.equals() method.
Long l;
try{
l = Long.parseLong(token);
} catch(NumberFormatException e){
//contains non-numeric character(s)
}
As for "transforming varchar into Long" - that sounds rather impossible, we do not have universally accepted way of doing that, and you did not provide one. However if I guess correctly that what you want is the number within the string disregarding the characters - you want regular expressions. The code you want could look like:
if (!StringUtils.isNumeric(token)){
String stripped = token.replaceAll("\\D","");
Long l = Long.parseLong(stripped);
}

Searching for words in textarea

I am building a custom a find and replace in java. I browse a text file and load the contents in a textarea. Now I have a textBox, where I input a text that needs to be searched.
What is the best way to search the text. I know a way using string.indexOf(), but I also need highlighting. So please help me out.
First of all read Text and New Lines for information on how to get the text to search.
Then to highlight the text your find you need to use a Highlighter. The code is something like:
Highlighter.HighlightPainter painter =
new DefaultHighlighter.DefaultHighlightPainter( Color.cyan );
int offset = text.indexOf(searchWord);
int length = searchWord.length();
while ( offset != -1)
{
try
{
textPane.getHighlighter().addHighlight(offset, offset + length, painter);
offset = text.indexOf(searchWord, offset+1);
}
catch(BadLocationException ble) { System.out.println(ble); }
}
indexOf is the easiest way, but might not be the fastest way.
Why isn't indexOf working for you? You will get the index of the match, and you know the length of the match, so just highlight the text that matched.
I am having the same problem with my text editor. I didn't use a highlighter though, I used
textArea.select(int i1, int i2); //where i1 is where your selection begins and i2 is where it ends.
also an easy way to find and replace is:
textArea.setText(textArea.getText().replaceAll(String string1, String string2));
final String inputValue = JOptionPane.showInputDialog("Find What?");
final int l1 = jTextArea1.getText().indexOf(inputValue);
final int l2 = inputValue.length();
if (l1 == -1) {
JOptionPane.showMessageDialog(null, "Search Value Not Found");
} else {
jTextArea1.select(l1, l2+l1);
}
if (e.getSource() == btnSearch && !searchWord.getText().isEmpty()) {
Highlighter.HighlightPainter painter =
new DefaultHighlighter.DefaultHighlightPainter( Color.cyan );
templateArea.getHighlighter().removeAllHighlights();
int offset = templateArea.getText().indexOf(searchWord.getText());
int length = searchWord.getText().length();
while ( offset != -1)
{
try
{
templateArea.getHighlighter().addHighlight(offset, offset + length, painter);
offset = templateArea.getText().indexOf(searchWord.getText(), offset+1);
}
catch(BadLocationException exception) { System.out.println(exception); }
}
}
}

Categories