Adjective position in a string resource - android

In French the position of the adjective can be before or after the noun. Depending of the length of the adjective, changing the position of the adjective can be mandatory to make a correct sentence. For example :
Bonne qualité nutritionnelle pour ce repas
Qualité nutritionnelle médiocre pour ce repas
I know plurals are implemented in Android, and also gender agreement with the SelectFormat class, but nothing on changing word order, e.g. adjective position, in a string resource.

You can use MessageFormat with a custom pattern. For that example:
String pattern = "{1, select, before {{0} qualité nutritionnelle} other {Qualité nutritionnelle {0}}} pour ce repas";
MessageFormat msgFmt = new MessageFormat(pattern, new ULocale("fr"));
Object args[] = {"Bonne", "before"};
Log.d("MessageFormatTAG",msgFmt.format(args));
Object args2[] = {"médiocre", "after"};
Log.d("MessageFormatTAG",msgFmt.format(args2))

Related

Replacing a word ignoring spaces and cases from a string in Android

What I'm trying to do:
if a String is
String a = "Love is rare"; Or
String a = "l o v e is rare"; Or
String a = "LO VE is rare";
Then,
I want the word "love" to be replaced by "hate" ignoring the space and case
My code:
a=a.toLowerCase().replace("love","hate").replace("\\s+","");
But the problem is that it removes all the spaces and change all the words to lower case. I just want to check if there is a word love by ignoring all the spaces and cases and if the word is there then replace it with some other word.
Please help!
Thank you.
Try it like this using an optional whitespace ? and the case insensitive flag. If you want to match zero or more whitespaces, you could use a whitespace and *
l ?o ?v ?e
String regex = "l ?o ?v ?e";
String[] lines = {"Love is rare", "l o v e is rare", "LO VE is rare"};
String subst = "hate";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
for (String line: lines) {
Matcher matcher = pattern.matcher(line);
String result = matcher.replaceAll(subst);
System.out.println(result);
}
That would give you:
hate is rare
hate is rare
hate is rare
Demo Java
Thanks for suggesting the term regex, Studied thoroughly and come up with this one line function which will replace "love" by "hate" ignoring the spaces and cases:
String a = "Lo ve is rare.";
Code:
a = a.replaceAll("(?i)l(\\s*)o(\\s*)v(\\s*)e","hate");
TextView.setText(a);
This would give:
hate is rare.

how to read from file raw and use in String.format

I want to read data from a raw file and replace the format in the text.
For example... In a raw file like this:
hello {0}, my name id {1}, my age is {2}....
When I use String.format, as shown below, the text loses its indentation.
String data = readTextFile(this, R.raw.input);
data = String.format(data, "world", "josh", "3");
Does anyone know how to do this without losing indentation?
Code that you provided looks more like String.format e.g from C#. String.format in Java does not work this way, it's more like printf.
You can manipulate your input to looks like this.
String input = "hello %s, my name id %s, my age is %s";
String.format(input, "world", "josh", "3");
output:
hello world, my name id josh, my age is 3
indentation should be the same
EDIT
If you want to use brackets you can use MessageFormat.format instead of String.format.
String messageInput = "hello {0}, my name id {1}, my age is {2}";
MessageFormat.format(messageInput,"world", "josh", "3");
You can use Regular Explessions with pattern like that: "{/d++}":
String format (String input, String... args) {
Pattern p = Pattern.compile("{/d++}");
String[] parts = p.split(input);
StringBuilder builder = new StringBuilder("");
int limit = Math.min(args.length, parts.length);
for(int i = 0; i < limit; i++){
builder.append(parts[i]).append(args[i]);
}
return builder.toString();
}
I found the solution for my problem.
there is a needed in one more variable, it's impossible to assignment into same variable
String data = readTextFile(this, R.raw.input);
String output = String.format(data, "world", "josh", "3");

Android TextView : "Do not concatenate text displayed with setText"

I am setting text using setText() by following way.
prodNameView.setText("" + name);
prodOriginalPriceView.setText("" + String.format(getString(R.string.string_product_rate_with_ruppe_sign), "" + new BigDecimal(price).setScale(2, RoundingMode.UP)));
In that First one is simple use and Second one is setting text with formatting text.
Android Studio is so much interesting, I used Menu Analyze -> Code Cleanup and i got suggestion on above two lines like.
Do not concatenate text displayed with setText. Use resource string
with placeholders. less... (Ctrl+F1)
When calling TextView#setText:
Never call Number#toString() to format numbers; it will not handle fraction separators and locale-specific digits properly. Consider
using String#format with proper format specifications (%d or %f)
instead.
Do not pass a string literal (e.g. "Hello") to display text. Hardcoded text can not be properly translated to other languages.
Consider using Android resource strings instead.
Do not build messages by concatenating text chunks. Such messages can not be properly translated.
What I can do for this? Anyone can help explain what the thing is and what should I do?
Resource has the get overloaded version of getString which takes a varargs of type Object: getString(int, java.lang.Object...). If you setup correctly your string in strings.xml, with the correct place holders, you can use this version to retrieve the formatted version of your final String. E.g.
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
using getString(R.string.welcome_message, "Test", 0);
android will return a String with
"Hello Test! you have 0 new messages"
About setText("" + name);
Your first Example, prodNameView.setText("" + name); doesn't make any sense to me. The TextView is able to handle null values. If name is null, no text will be drawn.
Don't get confused with %1$s and %2$d in the accepted answer.Here is a few extra information.
The format specifiers can be of the following syntax:
%[argument_index$]format_specifier
The optional argument_index is specified as a number ending with a “$” after the “%” and selects the specified argument in the argument list. The first argument is referenced by "1$", the second by "2$", etc.
The required format specifier is a character indicating how the argument should be formatted. The set of valid conversions for a given argument depends on the argument's data type.
Example
We will create the following formatted string where the gray parts are inserted programmatically.
Hello Test! you have 0 new messages
Your string resource:
< string name="welcome_messages">Hello, %1$s! You have %2$d new
messages< /string >
Do the string substitution as given below:
getString(R.string.welcome_message, "Test", 0);
Note:
%1$s will be substituted by the string "Test"
%2$d will be substituted by the string "0"
I ran into the same lint error message and solved it this way.
Initially my code was:
private void displayQuantity(int quantity) {
TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
quantityTextView.setText("" + quantity);
}
I got the following error
Do not concatenate text displayed with setText. Use resource string with placeholders.
So, I added this to strings.xml
<string name="blank">%d</string>
Which is my initial "" + a placeholder for my number(quantity).
Note: My quantity variable was previously defined and is what I wanted to append to the string. My code as a result was
private void displayQuantity(int quantity) {
TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view);
quantityTextView.setText(getString(R.string.blank, quantity));
}
After this, my error went away. The behavior in the app did not change and my quantity continued to display as I wanted it to now without a lint error.
Do not concatenate text inside your setText() method, Concatenate what ever you want in a String and put that String value inside your setText() method.
ex: correct way
int min = 120;
int sec = 200;
int hrs = 2;
String minutes = String.format("%02d", mins);
String seconds = String.format("%02d", secs);
String newTime = hrs+":"+minutes+":"+seconds;
text.setText(minutes);
Do not concatenate inside setText() like
text.setText(hrs+":"+String.format("%02d", mins)+":"+String.format("%02d", secs));
You should check this thread and use a placeholder like his one (not tested)
<string name="string_product_rate_with_ruppe_sign">Price : %1$d</string>
String text = String.format(getString(R.string.string_product_rate_with_ruppe_sign),new BigDecimal(price).setScale(2, RoundingMode.UP));
prodOriginalPriceView.setText(text);
Don't Mad, It's too Simple.
String firstname = firstname.getText().toString();
String result = "hi "+ firstname +" Welcome Here";
mytextview.setText(result);
the problem is because you are appending "" at the beginning of every string.
lint will scan arguments being passed to setText and will generate warnings, in your case following warning is relevant:
Do not build messages by
concatenating text chunks. Such messages can not be properly
translated.
as you are concatenating every string with "".
remove this concatenation as the arguments you are passing are already text. Also, you can use .toString() if at all required anywhere else instead of concatenating your string with ""
I fixed it by using String.format
befor :
textViewAddress.setText("Address"+address+"\n"+"nCountry"+"\n"+"City"+"city"+"\n"+"State"+"state")
after :
textViewAddress.setText(
String.format("Address:%s\nCountry:%s\nCity:%s\nState:%s", address, country, city, state));
You can use this , it works for me
title.setText(MessageFormat.format("{0} {1}", itemList.get(position).getOppName(), itemList.get(position).getBatchNum()));
If you don't need to support i18n, you can disable this lint check in Android Studio
File -> Settings -> Editor -> Inspections -> Android -> Lint -> TextView Internationalization(uncheck this)
prodNameView.setText("" + name); //this produce lint error
val nameStr="" + name;//workaround for quick warning fix require rebuild
prodNameView.setText(nameStr);
I know I am super late for answering this but I think you can store the data in a varible first then you can provide the variable name. eg:-
// Java syntax
String a = ("" + name);
String b = "" + String.format(getString(R.string.string_product_rate_with_ruppe_sign);
String c = "" + new BigDecimal(price).setScale(2, RoundingMode.UP));
prodNameView.setText(a);
prodOriginalPriceView.setText(b, c);
if it is textView you can use like that : myTextView.text = ("Hello World")
in editText you can use myTextView.setText("Hello World")

Regular expression with hebrew

I have text like:
לשלום קוראים לי משהmy test is עלות 39.40, כל מיני data 1.1.2015 ויש גם data 123456 מידע
This text have Hebrew and English characters, I need to eliminate all except the 6 digit number (may be 5, this num: 123456).
Can you help me with regular expression for this?
Tried:
String patternS = "[אבגדהוזחטיכךלמםנןסעפףצץקרשתa-fA-F0-9]{5,10}.*";
Pattern pattern = Pattern.compile(patternString);
With no success
To match everything except the number use:
\d+(?:[^\d]\d+)+|[\p{L}\p{M}\p{Z}\p{P}\p{S}\p{C}]+
String resultString = subjectString.replaceAll("\\d+(?:[^\\d]\\d+)+|[\\p{L}\\p{M}\\p{Z}\\p{P}\\p{S}\\p{C}]+", "");
This will give you every 6 didgit combination in your string.
(\d{6,6})
We can't give you a more detailled regex since we do now know the pattern of those strings.
In case there is always the "data " prefix you can also use this to make the pattern more accurate:
data (\d{6,6})
Try something like this:
String patternS = "(\d{5,6})";
Pattern pattern = Pattern.compile(patternS);
Matcher m = pattern.matcher(yourText);
int number = Integer.parseInt(m.group(1));
where yourText is the Hebrew/English text you want to match.
This would work for this specific example.
String s = " לשלום קוראים לי מש my test is עלות 39.40, כל מיני data 1.1.2015 ויש גם data 123456 מידע1234";
System.out.println(s.replaceAll(".*\\b(\\d{5,6})\\b.*", "$1"));

String input distributed to array (Android)?

I've been looking for answer regarding my question but I cannot find one or maybe I'm not just using the right terms when searching.
My question is, how can I distribute string entered in an editText to an array?
This is about my porter2 stemming project. I need to distribute the strings entered in the EditText field to an array so i can scan whether x in array[x] is vowel or not.
Ex.
String in EditText field = "dog".
Array should be:
array[0] = d
array[1] = o
array[2] = g
I'm sorry that i cannot give a code because I really don't have any idea how to code this one. Thank you so much everyone. :)
You can use use .split() with an empty ("") string input:
String text = yourEditText.getText().toString();
String[] letters = text.split(""); // Split by empty string to be in an array
// letters == { "", "d", "o", "g" }
// ^ Note that this has an empty string element at the front; that's just a byproduct of how split() works.
If you want a char array instead, it's much easier to use .toCharArray():
String text = yourEditText.getText().toString();
char[] letters = text.toCharArray();
// letters == { 'd', 'o', 'g' };
Personally I'd use the second one; letter == 'a' is a much faster operation than letter.equals("a").

Categories

Resources