I've been experimenting with various bits of Java code trying to come up with something that will encode a string containing quotes, spaces and "exotic" Unicode characters and produce output that's identical to JavaScript's encodeURIComponent function.
My torture test string is: "A" B ± "
If I enter the following JavaScript statement in Firebug:
encodeURIComponent('"A" B ± "');
—Then I get:
"%22A%22%20B%20%C2%B1%20%22"
Here's my little test Java program:
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class EncodingTest
{
public static void main(String[] args) throws UnsupportedEncodingException
{
String s = "\"A\" B ± \"";
System.out.println("URLEncoder.encode returns "
+ URLEncoder.encode(s, "UTF-8"));
System.out.println("getBytes returns "
+ new String(s.getBytes("UTF-8"), "ISO-8859-1"));
}
}
—This program outputs:
URLEncoder.encode returns %22A%22+B+%C2%B1+%22
getBytes returns "A" B ± "
Close, but no cigar! What is the best way of encoding a UTF-8 string using Java so that it produces the same output as JavaScript's encodeURIComponent?
EDIT: I'm using Java 1.4 moving to Java 5 shortly.
This is the class I came up with in the end:
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* Utility class for JavaScript compatible UTF-8 encoding and decoding.
*
* #see http://stackoverflow.com/questions/607176/java-equivalent-to-javascripts-encodeuricomponent-that-produces-identical-output
* #author John Topley
*/
public class EncodingUtil
{
/**
* Decodes the passed UTF-8 String using an algorithm that's compatible with
* JavaScript's <code>decodeURIComponent</code> function. Returns
* <code>null</code> if the String is <code>null</code>.
*
* #param s The UTF-8 encoded String to be decoded
* #return the decoded String
*/
public static String decodeURIComponent(String s)
{
if (s == null)
{
return null;
}
String result = null;
try
{
result = URLDecoder.decode(s, "UTF-8");
}
// This exception should never occur.
catch (UnsupportedEncodingException e)
{
result = s;
}
return result;
}
/**
* Encodes the passed String as UTF-8 using an algorithm that's compatible
* with JavaScript's <code>encodeURIComponent</code> function. Returns
* <code>null</code> if the String is <code>null</code>.
*
* #param s The String to be encoded
* #return the encoded String
*/
public static String encodeURIComponent(String s)
{
String result = null;
try
{
result = URLEncoder.encode(s, "UTF-8")
.replaceAll("\\+", "%20")
.replaceAll("\\%21", "!")
.replaceAll("\\%27", "'")
.replaceAll("\\%28", "(")
.replaceAll("\\%29", ")")
.replaceAll("\\%7E", "~");
}
// This exception should never occur.
catch (UnsupportedEncodingException e)
{
result = s;
}
return result;
}
/**
* Private constructor to prevent this class from being instantiated.
*/
private EncodingUtil()
{
super();
}
}
Looking at the implementation differences, I see that:
MDC on encodeURIComponent():
literal characters (regex representation): [-a-zA-Z0-9._*~'()!]
Java 1.5.0 documentation on URLEncoder:
literal characters (regex representation): [-a-zA-Z0-9._*]
the space character " " is converted into a plus sign "+".
So basically, to get the desired result, use URLEncoder.encode(s, "UTF-8") and then do some post-processing:
replace all occurrences of "+" with "%20"
replace all occurrences of "%xx" representing any of [~'()!] back to their literal counter-parts
Using the javascript engine that is shipped with Java 6:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Wow
{
public static void main(String[] args) throws Exception
{
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval("print(encodeURIComponent('\"A\" B ± \"'))");
}
}
Output: %22A%22%20B%20%c2%b1%20%22
The case is different but it's closer to what you want.
I use java.net.URI#getRawPath(), e.g.
String s = "a+b c.html";
String fixed = new URI(null, null, s, null).getRawPath();
The value of fixed will be a+b%20c.html, which is what you want.
Post-processing the output of URLEncoder.encode() will obliterate any pluses that are supposed to be in the URI. For example
URLEncoder.encode("a+b c.html").replaceAll("\\+", "%20");
will give you a%20b%20c.html, which will be interpreted as a b c.html.
I came up with my own version of the encodeURIComponent, because the posted solution has one problem, if there was a + present in the String, which should be encoded, it will converted to a space.
So here is my class:
import java.io.UnsupportedEncodingException;
import java.util.BitSet;
public final class EscapeUtils
{
/** used for the encodeURIComponent function */
private static final BitSet dontNeedEncoding;
static
{
dontNeedEncoding = new BitSet(256);
// a-z
for (int i = 97; i <= 122; ++i)
{
dontNeedEncoding.set(i);
}
// A-Z
for (int i = 65; i <= 90; ++i)
{
dontNeedEncoding.set(i);
}
// 0-9
for (int i = 48; i <= 57; ++i)
{
dontNeedEncoding.set(i);
}
// '()*
for (int i = 39; i <= 42; ++i)
{
dontNeedEncoding.set(i);
}
dontNeedEncoding.set(33); // !
dontNeedEncoding.set(45); // -
dontNeedEncoding.set(46); // .
dontNeedEncoding.set(95); // _
dontNeedEncoding.set(126); // ~
}
/**
* A Utility class should not be instantiated.
*/
private EscapeUtils()
{
}
/**
* Escapes all characters except the following: alphabetic, decimal digits, - _ . ! ~ * ' ( )
*
* #param input
* A component of a URI
* #return the escaped URI component
*/
public static String encodeURIComponent(String input)
{
if (input == null)
{
return input;
}
StringBuilder filtered = new StringBuilder(input.length());
char c;
for (int i = 0; i < input.length(); ++i)
{
c = input.charAt(i);
if (dontNeedEncoding.get(c))
{
filtered.append(c);
}
else
{
final byte[] b = charToBytesUTF(c);
for (int j = 0; j < b.length; ++j)
{
filtered.append('%');
filtered.append("0123456789ABCDEF".charAt(b[j] >> 4 & 0xF));
filtered.append("0123456789ABCDEF".charAt(b[j] & 0xF));
}
}
}
return filtered.toString();
}
private static byte[] charToBytesUTF(char c)
{
try
{
return new String(new char[] { c }).getBytes("UTF-8");
}
catch (UnsupportedEncodingException e)
{
return new byte[] { (byte) c };
}
}
}
I came up with another implementation documented at, http://blog.sangupta.com/2010/05/encodeuricomponent-and.html. The implementation can also handle Unicode bytes.
This is a straightforward example Ravi Wallau's solution:
public String buildSafeURL(String partialURL, String documentName)
throws ScriptException {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager
.getEngineByName("JavaScript");
String urlSafeDocumentName = String.valueOf(scriptEngine
.eval("encodeURIComponent('" + documentName + "')"));
String safeURL = partialURL + urlSafeDocumentName;
return safeURL;
}
public static void main(String[] args) {
EncodeURIComponentDemo demo = new EncodeURIComponentDemo();
String partialURL = "https://www.website.com/document/";
String documentName = "Tom & Jerry Manuscript.pdf";
try {
System.out.println(demo.buildSafeURL(partialURL, documentName));
} catch (ScriptException se) {
se.printStackTrace();
}
}
Output:
https://www.website.com/document/Tom%20%26%20Jerry%20Manuscript.pdf
It also answers the hanging question in the comments by Loren Shqipognja on how to pass a String variable to encodeURIComponent(). The method scriptEngine.eval() returns an Object, so it can converted to String via String.valueOf() among other methods.
I have found PercentEscaper class from google-http-java-client library, that can be used to implement encodeURIComponent quite easily.
PercentEscaper from google-http-java-client javadoc
google-http-java-client home
I have successfully used the java.net.URI class like so:
public static String uriEncode(String string) {
String result = string;
if (null != string) {
try {
String scheme = null;
String ssp = string;
int es = string.indexOf(':');
if (es > 0) {
scheme = string.substring(0, es);
ssp = string.substring(es + 1);
}
result = (new URI(scheme, ssp, null)).toString();
} catch (URISyntaxException usex) {
// ignore and use string that has syntax error
}
}
return result;
}
for me this worked:
import org.apache.http.client.utils.URIBuilder;
String encodedString = new URIBuilder()
.setParameter("i", stringToEncode)
.build()
.getRawQuery() // output: i=encodedString
.substring(2);
or with a different UriBuilder
import javax.ws.rs.core.UriBuilder;
String encodedString = UriBuilder.fromPath("")
.queryParam("i", stringToEncode)
.toString() // output: ?i=encodedString
.substring(3);
In my opinion using a standard library is a better idea rather than post processing manually. Also #Chris answer looked good, but it doesn't work for urls, like "http://a+b c.html"
Guava library has PercentEscaper:
Escaper percentEscaper = new PercentEscaper("-_.*", false);
"-_.*" are safe characters
false says PercentEscaper to escape space with '%20', not '+'
This is what I'm using:
private static final String HEX = "0123456789ABCDEF";
public static String encodeURIComponent(String str) {
if (str == null) return null;
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
StringBuilder builder = new StringBuilder(bytes.length);
for (byte c : bytes) {
if (c >= 'a' ? c <= 'z' || c == '~' :
c >= 'A' ? c <= 'Z' || c == '_' :
c >= '0' ? c <= '9' : c == '-' || c == '.')
builder.append((char)c);
else
builder.append('%')
.append(HEX.charAt(c >> 4 & 0xf))
.append(HEX.charAt(c & 0xf));
}
return builder.toString();
}
It goes beyond Javascript's by percent-encoding every character that is not an unreserved character according to RFC 3986.
This is the oposite conversion:
public static String decodeURIComponent(String str) {
if (str == null) return null;
int length = str.length();
byte[] bytes = new byte[length / 3];
StringBuilder builder = new StringBuilder(length);
for (int i = 0; i < length; ) {
char c = str.charAt(i);
if (c != '%') {
builder.append(c);
i += 1;
} else {
int j = 0;
do {
char h = str.charAt(i + 1);
char l = str.charAt(i + 2);
i += 3;
h -= '0';
if (h >= 10) {
h |= ' ';
h -= 'a' - '0';
if (h >= 6) throw new IllegalArgumentException();
h += 10;
}
l -= '0';
if (l >= 10) {
l |= ' ';
l -= 'a' - '0';
if (l >= 6) throw new IllegalArgumentException();
l += 10;
}
bytes[j++] = (byte)(h << 4 | l);
if (i >= length) break;
c = str.charAt(i);
} while (c == '%');
builder.append(new String(bytes, 0, j, UTF_8));
}
}
return builder.toString();
}
I used
String encodedUrl = new URI(null, url, null).toASCIIString();
to encode urls.
To add parameters after the existing ones in the url I use UriComponentsBuilder
Related
I have a string in format AB123. I want to split it between the AB and 123 so AB123 becomes AB 123. The contents of the string can differ but the format stays the same. Is there a way to do this?
Following up with the latest information you provided (2 letters then 3 numbers):
myString.subString(0, 2) + " " + myString.subString(2)
What this does: you split your input string myString at the 2nd character and append a space at this position.
Explanation: \D represents non-digit and \d represents a digit in a regular expression and I used ternary operation in the regex to split charter to the number.
String string = "AB123";
String[] split = string.split("(?<=\\D)(?=\\d)");
System.out.println(split[0]+" "+split[1]);
Try
String a = "abcd1234";
int i;
for(i = 0; i < a.length(); i++){
char c = a.charAt(i);
if( '0' <= c && c <= '9' )
break;
}
String alphaPart = a.substring(0, i);
String numberPart = a.substring(i);
Hope this helps
Although I would personally use the method provided in #RakeshMothukur's answer, since it also works when the letter or digit counts increase/decrease later on, I wanted to provide an additional method to insert the space between the two letters and three digits:
String str = "AB123";
StringBuilder sb = new StringBuilder(str);
sb.insert(2, " "); // Insert a space at 0-based index 2; a.k.a. after the first 2 characters
String result = sb.toString(); // Convert the StringBuilder back to a String
Try it online.
Here you go. I wrote it in very simple way to make things clear.
What it does is : After it takes user input, it converts the string into Char array and it checks single character if its INT or non INT.
In each iteration it compares the data type with the prev character and prints accordingly.
Alternate Solutions
1) Using ASCII range (difficulty = easy)
2) Override a method and check 2 variables at a time. (difficulty = Intermediate)
import org.omg.CORBA.INTERNAL;
import java.io.InputStreamReader;
import java.util.*;
import java.io.BufferedReader;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[] s = br.readLine().toCharArray();
int prevflag, flag = 0;
for (int i = 0; i < s.length; i++) {
int a = Character.getNumericValue(s[i]);
String b = String.valueOf(s[i]);
prevflag = flag;
flag = checktype(a, b);
if ((prevflag == flag) || (i == 0))
System.out.print(s[i]);
else
System.out.print(" " + s[i]);
}
}
public static int checktype(int x, String y) {
int flag = 0;
if (String.valueOf(x).equals(y))
flag = 1; // INT
else
flag = 2; // non INT
return flag;
}
}
I was waiting for a compile to finish before heading out, so threw together a slightly over-engineered example with basic error checking and a test.
import java.text.ParseException;
import java.util.LinkedList;
public class Main {
static public class ParsedData {
public final String prefix;
public final Integer number;
public ParsedData(String _prefix, Integer _number) {
prefix = _prefix;
number = _number;
}
#Override
public String toString() {
return prefix + "\t" + number.toString();
}
}
static final String TEST_DATA[] = {"AB123", "JX7272", "FX402", "ADF123", "JD3Q2", "QB778"};
public static void main(String[] args) {
parseDataArray(TEST_DATA);
}
public static ParsedData[] parseDataArray(String[] inputs) {
LinkedList<ParsedData> results = new LinkedList<ParsedData>();
for (String s : TEST_DATA) {
try {
System.out.println("Parsing: " + s);
if (s.length() != 5) throw new ParseException("Input Length incorrect: " + s.length(), 0);
String _prefix = s.substring(0, 2);
Integer _num = Integer.parseInt(s.substring(2));
results.add(new ParsedData(_prefix, _num));
} catch (ParseException | NumberFormatException e) {
System.out.printf("\"%s\", %s\n", s, e.toString());
}
}
return results.toArray(new ParsedData[results.size()]);
}
}
For accessing individual characters of a String in Java, we have String.charAt(2). Is there any inbuilt function to remove an individual character of a String in java?
Something like this:
if(String.charAt(1) == String.charAt(2){
//I want to remove the individual character at index 2.
}
You can also use the StringBuilder class which is mutable.
StringBuilder sb = new StringBuilder(inputString);
It has the method deleteCharAt(), along with many other mutator methods.
Just delete the characters that you need to delete and then get the result as follows:
String resultString = sb.toString();
This avoids creation of unnecessary string objects.
You can use Java String method called replace, which will replace all characters matching the first parameter with the second parameter:
String a = "Cool";
a = a.replace("o","");
One possibility:
String result = str.substring(0, index) + str.substring(index+1);
Note that the result is a new String (as well as two intermediate String objects), because Strings in Java are immutable.
No, because Strings in Java are immutable. You'll have to create a new string removing the character you don't want.
For replacing a single char c at index position idx in string str, do something like this, and remember that a new string will be created:
String newstr = str.substring(0, idx) + str.substring(idx + 1);
String str = "M1y java8 Progr5am";
deleteCharAt()
StringBuilder build = new StringBuilder(str);
System.out.println("Pre Builder : " + build);
build.deleteCharAt(1); // Shift the positions front.
build.deleteCharAt(8-1);
build.deleteCharAt(15-2);
System.out.println("Post Builder : " + build);
replace()
StringBuffer buffer = new StringBuffer(str);
buffer.replace(1, 2, ""); // Shift the positions front.
buffer.replace(7, 8, "");
buffer.replace(13, 14, "");
System.out.println("Buffer : "+buffer);
char[]
char[] c = str.toCharArray();
String new_Str = "";
for (int i = 0; i < c.length; i++) {
if (!(i == 1 || i == 8 || i == 15))
new_Str += c[i];
}
System.out.println("Char Array : "+new_Str);
To modify Strings, read about StringBuilder because it is mutable except for immutable String. Different operations can be found here https://docs.oracle.com/javase/tutorial/java/data/buffers.html. The code snippet below creates a StringBuilder and then append the given String and then delete the first character from the String and then convert it back from StringBuilder to a String.
StringBuilder sb = new StringBuilder();
sb.append(str);
sb.deleteCharAt(0);
str = sb.toString();
Consider the following code:
public String removeChar(String str, Integer n) {
String front = str.substring(0, n);
String back = str.substring(n+1, str.length());
return front + back;
}
You may also use the (huge) regexp machine.
inputString = inputString.replaceFirst("(?s)(.{2}).(.*)", "$1$2");
"(?s)" - tells regexp to handle newlines like normal characters (just in case).
"(.{2})" - group $1 collecting exactly 2 characters
"." - any character at index 2 (to be squeezed out).
"(.*)" - group $2 which collects the rest of the inputString.
"$1$2" - putting group $1 and group $2 together.
If you want to remove a char from a String str at a specific int index:
public static String removeCharAt(String str, int index) {
// The part of the String before the index:
String str1 = str.substring(0,index);
// The part of the String after the index:
String str2 = str.substring(index+1,str.length());
// These two parts together gives the String without the specified index
return str1+str2;
}
By the using replace method we can change single character of string.
string= string.replace("*", "");
Use replaceFirst function of String class. There are so many variants of replace function that you can use.
If you need some logical control over character removal, use this
String string = "sdsdsd";
char[] arr = string.toCharArray();
// Run loop or whatever you need
String ss = new String(arr);
If you don't need any such control, you can use what Oscar orBhesh mentioned. They are spot on.
Easiest way to remove a char from string
String str="welcome";
str=str.replaceFirst(String.valueOf(str.charAt(2)),"");//'l' will replace with ""
System.out.println(str);//output: wecome
public class RemoveCharFromString {
public static void main(String[] args) {
String output = remove("Hello", 'l');
System.out.println(output);
}
private static String remove(String input, char c) {
if (input == null || input.length() <= 1)
return input;
char[] inputArray = input.toCharArray();
char[] outputArray = new char[inputArray.length];
int outputArrayIndex = 0;
for (int i = 0; i < inputArray.length; i++) {
char p = inputArray[i];
if (p != c) {
outputArray[outputArrayIndex] = p;
outputArrayIndex++;
}
}
return new String(outputArray, 0, outputArrayIndex);
}
}
In most use-cases using StringBuilder or substring is a good approach (as already answered). However, for performance critical code, this might be a good alternative.
/**
* Delete a single character from index position 'start' from the 'target' String.
*
* ````
* deleteAt("ABC", 0) -> "BC"
* deleteAt("ABC", 1) -> "B"
* deleteAt("ABC", 2) -> "C"
* ````
*/
public static String deleteAt(final String target, final int start) {
return deleteAt(target, start, start + 1);
}
/**
* Delete the characters from index position 'start' to 'end' from the 'target' String.
*
* ````
* deleteAt("ABC", 0, 1) -> "BC"
* deleteAt("ABC", 0, 2) -> "C"
* deleteAt("ABC", 1, 3) -> "A"
* ````
*/
public static String deleteAt(final String target, final int start, int end) {
final int targetLen = target.length();
if (start < 0) {
throw new IllegalArgumentException("start=" + start);
}
if (end > targetLen || end < start) {
throw new IllegalArgumentException("end=" + end);
}
if (start == 0) {
return end == targetLen ? "" : target.substring(end);
} else if (end == targetLen) {
return target.substring(0, start);
}
final char[] buffer = new char[targetLen - end + start];
target.getChars(0, start, buffer, 0);
target.getChars(end, targetLen, buffer, start);
return new String(buffer);
}
*You can delete string value use the StringBuilder and deletecharAt.
String s1 = "aabc";
StringBuilder sb = new StringBuilder(s1);
for(int i=0;i<sb.length();i++)
{
char temp = sb.charAt(0);
if(sb.indexOf(temp+"")!=1)
{
sb.deleteCharAt(sb.indexOf(temp+""));
}
}
To Remove a Single character from The Given String please find my method hope it will be usefull. i have used str.replaceAll to remove the string but their are many ways to remove a character from a given string but i prefer replaceall method.
Code For Remove Char:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class Removecharacter
{
public static void main(String[] args)
{
String result = removeChar("Java", 'a');
String result1 = removeChar("Edition", 'i');
System.out.println(result + " " + result1);
}
public static String removeChar(String str, char c) {
if (str == null)
{
return null;
}
else
{
return str.replaceAll(Character.toString(c), "");
}
}
}
Console image :
please find The Attached image of console,
Thanks For Asking. :)
public static String removechar(String fromString, Character character) {
int indexOf = fromString.indexOf(character);
if(indexOf==-1)
return fromString;
String front = fromString.substring(0, indexOf);
String back = fromString.substring(indexOf+1, fromString.length());
return front+back;
}
BufferedReader input=new BufferedReader(new InputStreamReader(System.in));
String line1=input.readLine();
String line2=input.readLine();
char[] a=line2.toCharArray();
char[] b=line1.toCharArray();
loop: for(int t=0;t<a.length;t++) {
char a1=a[t];
for(int t1=0;t1<b.length;t1++) {
char b1=b[t1];
if(a1==b1) {
StringBuilder sb = new StringBuilder(line1);
sb.deleteCharAt(t1);
line1=sb.toString();
b=line1.toCharArray();
list.add(a1);
continue loop;
}
}
When I have these kinds of questions I always ask: "what would the Java Gurus do?" :)
And I'd answer that, in this case, by looking at the implementation of String.trim().
Here's an extrapolation of that implementation that allows for more trim characters to be used.
However, note that original trim actually removes all chars that are <= ' ', so you may have to combine this with the original to get the desired result.
String trim(String string, String toTrim) {
// input checks removed
if (toTrim.length() == 0)
return string;
final char[] trimChars = toTrim.toCharArray();
Arrays.sort(trimChars);
int start = 0;
int end = string.length();
while (start < end &&
Arrays.binarySearch(trimChars, string.charAt(start)) >= 0)
start++;
while (start < end &&
Arrays.binarySearch(trimChars, string.charAt(end - 1)) >= 0)
end--;
return string.substring(start, end);
}
public String missingChar(String str, int n) {
String front = str.substring(0, n);
// Start this substring at n+1 to omit the char.
// Can also be shortened to just str.substring(n+1)
// which goes through the end of the string.
String back = str.substring(n+1, str.length());
return front + back;
}
I just implemented this utility class that removes a char or a group of chars from a String. I think it's fast because doesn't use Regexp. I hope that it helps someone!
package your.package.name;
/**
* Utility class that removes chars from a String.
*
*/
public class RemoveChars {
public static String remove(String string, String remove) {
return new String(remove(string.toCharArray(), remove.toCharArray()));
}
public static char[] remove(final char[] chars, char[] remove) {
int count = 0;
char[] buffer = new char[chars.length];
for (int i = 0; i < chars.length; i++) {
boolean include = true;
for (int j = 0; j < remove.length; j++) {
if ((chars[i] == remove[j])) {
include = false;
break;
}
}
if (include) {
buffer[count++] = chars[i];
}
}
char[] output = new char[count];
System.arraycopy(buffer, 0, output, 0, count);
return output;
}
/**
* For tests!
*/
public static void main(String[] args) {
String string = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG";
String remove = "AEIOU";
System.out.println();
System.out.println("Remove AEIOU: " + string);
System.out.println("Result: " + RemoveChars.remove(string, remove));
}
}
This is the output:
Remove AEIOU: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
Result: TH QCK BRWN FX JMPS VR TH LZY DG
For example if you want to calculate how many a's are there in the String, you can do it like this:
if (string.contains("a"))
{
numberOf_a++;
string = string.replaceFirst("a", "");
}
I need to convert Arabic/Persian Numbers to its English equal (for example convert "۲" to "2")
How can I do this?
I suggest you have a ten digit lookup String and replace all the digits one at a time.
public static void main(String... args) {
System.out.println(arabicToDecimal("۴۲"));
}
//used in Persian apps
private static final String extendedArabic = "\u06f0\u06f1\u06f2\u06f3\u06f4\u06f5\u06f6\u06f7\u06f8\u06f9";
//used in Arabic apps
private static final String arabic = "\u0660\u0661\u0662\u0663\u0664\u0665\u0666\u0667\u0668\u0669";
private static String arabicToDecimal(String number) {
char[] chars = new char[number.length()];
for(int i=0;i<number.length();i++) {
char ch = number.charAt(i);
if (ch >= 0x0660 && ch <= 0x0669)
ch -= 0x0660 - '0';
else if (ch >= 0x06f0 && ch <= 0x06F9)
ch -= 0x06f0 - '0';
chars[i] = ch;
}
return new String(chars);
}
prints
42
The reason for using the strings as a lookup is that other characters such as . - , would be left as is. In fact a decimal number would be unchanged.
I achived this by java.math.BigDecimal Class, Below is the code snippet
String arabicNumerals = "۴۲۴۲.۴۲";
String englishNumerals = new BigDecimal(arabic).toString();
System.out.println("Number In Arabic : "+arabicNumerals);
System.out.println("Number In English : "+englishNumerals);
Result
Number In Arabic : ۴۲۴۲.۴۲
Number In English : 4242.42
NB: The above code will not work if there are any characteors other than numeric digits in arabicNumerals, for example: ۴,۲۴۲.۴۲ will result in a java.lang.NumberFormatException, so you may remove other characters using Character.isDigit(char ch) in another logic and use the above code. All normal cases are working.
I found a simpler and faster way which includes the two arabic code pages too.
public static String convertToEnglishDigits(String value)
{
String newValue = value.replace("١", "1").replace("٢", "2").replace("٣", "3").replace("٤", "4").replace("٥", "5")
.replace("٦", "6").replace("7", "٧").replace("٨", "8").replace("٩", "9").replace("٠", "0")
.replace("۱", "1").replace("۲", "2").replace("۳", "3").replace("۴", "4").replace("۵", "5")
.replace("۶", "6").replace("۷", "7").replace("۸", "8").replace("۹", "9").replace("۰", "0");
return newValue;
}
It will return the numbers in English format or vise versa if you change the replace from.
("۰", "0") to ("0","۰")
Try this guys:
/**
* Utility class to detect arabic languages and convert numbers into arabic digits.
*
* #author Ahmed Shakil
* #date 09-24-2012
*/
public final class ArabicUtil {
private static final char[] DIGITS = {'\u0660','\u0661','\u0662','\u0663','\u0664','\u0665','\u0666','\u0667','\u0668','\u0669'};
/**
* Returns <code>true</code> if the provided language code uses arabic characters; othersise <code>false</code>.
* #param lang ISO language code.
* #return <code>true</code> if the provided language code uses arabic characters; othersise <code>false</code>
*/
public static boolean isArabic (String lang) {
return "ar".equals(lang) || "fa".equals(lang) || "ur".equals(lang);
}
/**
* Convert digits in the specified string to arabic digits.
*/
public static String convertDigits (String str) {
if (str == null || str.length() == 0) return str;
char[] s = new char[str.length()];
for(int i =0;i<s.length;i++)
s[i] = toDigit( str.charAt( i ) );
return new String(s);
}
/**
* Convert single digit in the specified string to arabic digit.
*/
public static char toDigit (char ch) {
int n = Character.getNumericValue( (int)ch );
return n >=0 && n < 10 ? ARABIC[n] : ch;
}
/**
* Convert an int into arabic string.
*/
public static String toString (int num) {
return convertDigits( Integer.toString( num ) );
}
}
BTW there is a difference between arabic digits vs. urdu/farsi:
Arabic:
private static final char[] ARABIC = {'\u0660', '\u0661', '\u0662', '\u0663', '\u0664', '\u0665', '\u0666', '\u0667', '\u0668', '\u0669'};
Urdu or Farsi:
private static final char[] URDU_FARSI = {'\u06f0', '\u06f1', '\u06f2', '\u06f3', '\u06f4', '\u06f5', '\u06f6', '\u06f7', '\u06f8', '\u06f9'};
First make it work, then make it look nice ;-)
public static char persianDigitToEnglish(char persianDigit) {
return (char) (((int)persianDigit) - ((int)'۲' - (int)'2'));
}
Works for 2, unfortunately I don't know other Persian digits, could You give it a try?
assertThat(persianDigitToEnglish('۲')).isEqualTo('2');
EDIT: (based on Peter Lawrey String version, but uses StringBuilder)
public static String persianDigitToEnglish(String persianNumber) {
StringBuilder chars = new StringBuilder(persianNumber.length());
for (int i = 0; i < persianNumber.length(); i++)
chars.append(persianDigitToEnglish(persianNumber.charAt(i)));
return chars.toString();
}
private static char persianDigitToEnglish(char persianDigit) {
return (char) (((int)persianDigit) - ((int)'۲' - (int)'2'));
}
so trivial answer:
public static String convertNumbersToPersian(String str)
{
String answer = str;
answer = answer.replace("1","١");
answer = answer.replace("2","٢");
answer = answer.replace("3","٣");
answer = answer.replace("4","٤");
answer = answer.replace("5","٥");
answer = answer.replace("6","٦");
answer = answer.replace("7","٧");
answer = answer.replace("8","٨");
answer = answer.replace("9","٩");
answer = answer.replace("0","٠");
return answer;
}
and
public static String convertNumbersToEnglish(String str) {
String answer = str;
answer = answer.replace("١", "1");
answer = answer.replace("٢", "2");
answer = answer.replace("٣", "3");
answer = answer.replace("٤", "4");
answer = answer.replace("٥", "5");
answer = answer.replace("٦", "6");
answer = answer.replace("٧", "7");
answer = answer.replace("٨", "8");
answer = answer.replace("٩", "9");
answer = answer.replace("٠", "0");
return answer;
}
Character.getNumericValue(ch) saved my life, generic solution for any locale.
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 (Character.isDigit(ch) && !(ch >= '0' && ch <= '9')) {
int numericValue = Character.getNumericValue(ch);
if (numericValue >= 0) {
builder.append(numericValue);
}
} else {
builder.append(ch);
}
}
return builder.toString();
}
i think the best way is to change the Locale to what you want for example,
for double number :
NumberFormat fmt = NumberFormat.getNumberInstance(Locale.US);
d = Double.parseDouble(s);
for String :
NumberFormat.getNumberInstance(Locale.US).format(s);
or DecimalFormat:
double num;
DecimalFormat df = new DecimalFormat("###.###");
df.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
String s = df.format(num);
While I was looking for the most performant solution I mixed Kishath and Sileria answers and came up with a clean and fast result:
public class StringLocalizer {
private static final char[] ENGLISH_NUMBERS = {'\u0030', '\u0031', '\u0032', '\u0033', '\u0034', '\u0035', '\u0036', '\u0037', '\u0038', '\u0039'};
private static final char[] PERSIAN_NUMBERS = {'\u06f0', '\u06f1', '\u06f2', '\u06f3', '\u06f4', '\u06f5', '\u06f6', '\u06f7', '\u06f8', '\u06f9'};
private static final char[] ARABIC_NUMBERS = {'\u0660', '\u0661', '\u0662', '\u0663', '\u0664', '\u0665', '\u0666', '\u0667', '\u0668', '\u0669'};
public static String on(String input) {
String lang = Locale.getDefault().getLanguage();
boolean isPersian = "fa".equals(lang) || "ur".equals(lang);
boolean isArabic = "ar".equals(lang);
if (isPersian) return input
.replace(ENGLISH_NUMBERS[0], PERSIAN_NUMBERS[0])
.replace(ENGLISH_NUMBERS[1], PERSIAN_NUMBERS[1])
.replace(ENGLISH_NUMBERS[2], PERSIAN_NUMBERS[2])
.replace(ENGLISH_NUMBERS[3], PERSIAN_NUMBERS[3])
.replace(ENGLISH_NUMBERS[4], PERSIAN_NUMBERS[4])
.replace(ENGLISH_NUMBERS[5], PERSIAN_NUMBERS[5])
.replace(ENGLISH_NUMBERS[6], PERSIAN_NUMBERS[6])
.replace(ENGLISH_NUMBERS[7], PERSIAN_NUMBERS[7])
.replace(ENGLISH_NUMBERS[8], PERSIAN_NUMBERS[8])
.replace(ENGLISH_NUMBERS[9], PERSIAN_NUMBERS[9]);
else if (isArabic) return input
.replace(ENGLISH_NUMBERS[0], ARABIC_NUMBERS[0])
.replace(ENGLISH_NUMBERS[1], ARABIC_NUMBERS[1])
.replace(ENGLISH_NUMBERS[2], ARABIC_NUMBERS[2])
.replace(ENGLISH_NUMBERS[3], ARABIC_NUMBERS[3])
.replace(ENGLISH_NUMBERS[4], ARABIC_NUMBERS[4])
.replace(ENGLISH_NUMBERS[5], ARABIC_NUMBERS[5])
.replace(ENGLISH_NUMBERS[6], ARABIC_NUMBERS[6])
.replace(ENGLISH_NUMBERS[7], ARABIC_NUMBERS[7])
.replace(ENGLISH_NUMBERS[8], ARABIC_NUMBERS[8])
.replace(ENGLISH_NUMBERS[9], ARABIC_NUMBERS[9]);
else return input
.replace(PERSIAN_NUMBERS[0], ENGLISH_NUMBERS[0])
.replace(PERSIAN_NUMBERS[1], ENGLISH_NUMBERS[1])
.replace(PERSIAN_NUMBERS[2], ENGLISH_NUMBERS[2])
.replace(PERSIAN_NUMBERS[3], ENGLISH_NUMBERS[3])
.replace(PERSIAN_NUMBERS[4], ENGLISH_NUMBERS[4])
.replace(PERSIAN_NUMBERS[5], ENGLISH_NUMBERS[5])
.replace(PERSIAN_NUMBERS[6], ENGLISH_NUMBERS[6])
.replace(PERSIAN_NUMBERS[7], ENGLISH_NUMBERS[7])
.replace(PERSIAN_NUMBERS[8], ENGLISH_NUMBERS[8])
.replace(PERSIAN_NUMBERS[9], ENGLISH_NUMBERS[9])
.replace(ARABIC_NUMBERS[0], ENGLISH_NUMBERS[0])
.replace(ARABIC_NUMBERS[1], ENGLISH_NUMBERS[1])
.replace(ARABIC_NUMBERS[2], ENGLISH_NUMBERS[2])
.replace(ARABIC_NUMBERS[3], ENGLISH_NUMBERS[3])
.replace(ARABIC_NUMBERS[4], ENGLISH_NUMBERS[4])
.replace(ARABIC_NUMBERS[5], ENGLISH_NUMBERS[5])
.replace(ARABIC_NUMBERS[6], ENGLISH_NUMBERS[6])
.replace(ARABIC_NUMBERS[7], ENGLISH_NUMBERS[7])
.replace(ARABIC_NUMBERS[8], ENGLISH_NUMBERS[8])
.replace(ARABIC_NUMBERS[9], ENGLISH_NUMBERS[9]);
}
}
Note that here we assumed localizing is done between English and Persian or Arabic, so if you also need to include another language in replacing criteria just add the missing replace clauses.
This code will work with decimal points also:
public class mainsupport {
public static void main(String args[]){
// String Numtoconvert="15.3201" ;
// String Numtoconvert="458" ;
String Numtoconvert="٨٧٫٥٩٨" ; // integer value 87.598
System.out.println(getUSNumber(Numtoconvert));
}
private static String getUSNumber(String Numtoconvert){
NumberFormat formatter = NumberFormat.getInstance(Locale.US);
try {
if(Numtoconvert.contains("٫"))
Numtoconvert=formatter.parse(Numtoconvert.split("٫")[0].trim())+"."+formatter.parse(Numtoconvert.split("٫")[1].trim());
else
Numtoconvert=formatter.parse(Numtoconvert).toString();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return Numtoconvert;
}
This prints 87.598.
The following seems to me to be the simple and obvious solution. I don’t know why it hasn’t been posted before.
Locale persian = Locale.forLanguageTag("fa");
NumberFormat nf = NumberFormat.getIntegerInstance(persian);
String persianIntegerString = "۲۱";
int parsedInteger = nf.parse(persianIntegerString).intValue();
System.out.println(parsedInteger);
Output is:
21
If we’ve got a string with a decimal point in it (or just one that may have that), use getInstance instead of getIntegerInstance. At the same time I am taking an Arabic string this time to demonstrate that this works too.
Locale arabic = Locale.forLanguageTag("ar");
NumberFormat nf = NumberFormat.getInstance(arabic);
String arabicDecimalString = "٣٤٫٥٦";
double parsedDouble = nf.parse(arabicDecimalString).doubleValue();
System.out.println(parsedDouble);
34.56
In many cases the number formats can also parse numbers in other locales, but I doubt that it is always the case, so I would not want to rely on it.
Use Locale class to convert numbers.
Locale locale = new Locale("ar");
String formattedArabic = format(locale, "%d", value));
Try this for converting Persian/Arabic numbers to English:
public static String convertToEnglish(String arabicNumber) {
for (int i = 0; i <= 9; i++) {
arabicNumber= arabicNumber.replace((char) (1776 + i),
(char) (48 + i));
}
return arabicNumber;
}
I think instead of replacing the digits one by one (which would only work for decimal numbers), you should parse your number with a persian NumberFormat to a number, and then (if necessary) use a english NumberFormat to format it again.
it may seem simple but it posses lots of bugs
I tried this way:
String s = gameList[0].toString();
s.replaceFirst(String.valueOf(s.charAt(0)),String.valueOf(Character.toUpperCase(s.charAt(0))) );
and it throws an exception
another try i had was :
String s = gameList[0].toString();
char c = Character.toUpperCase(gameList[0].charAt(0));
gameList[0] = s.subSequence(1, s.length());
rhis one also throws an Exception
/**
* returns the string, the first char lowercase
*
* #param target
* #return
*/
public final static String asLowerCaseFirstChar(final String target) {
if ((target == null) || (target.length() == 0)) {
return target; // You could omit this check and simply live with an
// exception if you like
}
return Character.toLowerCase(target.charAt(0))
+ (target.length() > 1 ? target.substring(1) : "");
}
/**
* returns the string, the first char uppercase
*
* #param target
* #return
*/
public final static String asUpperCaseFirstChar(final String target) {
if ((target == null) || (target.length() == 0)) {
return target; // You could omit this check and simply live with an
// exception if you like
}
return Character.toUpperCase(target.charAt(0))
+ (target.length() > 1 ? target.substring(1) : "");
}
. . . or do it all in an array. Here's something similar.
String titleize(String source){
boolean cap = true;
char[] out = source.toCharArray();
int i, len = source.length();
for(i=0; i<len; i++){
if(Character.isWhitespace(out[i])){
cap = true;
continue;
}
if(cap){
out[i] = Character.toUpperCase(out[i]);
cap = false;
}
}
return new String(out);
}
On String being immutable
Regarding your first attempt:
String s = gameList[0].toString();
s.replaceFirst(...);
Java strings are immutable. You can't invoke a method on a string instance and expect the method to modify that string. replaceFirst instead returns a new string. This means that these kinds of usage are wrong:
s1.trim();
s2.replace("x", "y");
Instead, you'd want to do something like this:
s1 = s1.trim();
s2 = s2.replace("x", "y");
As for changing the first letter of a CharSequence to uppercase, something like this works (as seen on ideone.com):
static public CharSequence upperFirst(CharSequence s) {
if (s.length() == 0) {
return s;
} else {
return Character.toUpperCase(s.charAt(0))
+ s.subSequence(1, s.length()).toString();
}
}
public static void main(String[] args) {
String[] tests = {
"xyz", "123 abc", "x", ""
};
for (String s : tests) {
System.out.printf("[%s]->[%s]%n", s, upperFirst(s));
}
// [xyz]->[Xyz]
// [123 abc]->[123 abc]
// [x]->[X]
// []->[]
StringBuilder sb = new StringBuilder("blah");
System.out.println(upperFirst(sb));
// prints "Blah"
}
This of course will throw NullPointerException if s == null. This is often an appropriate behavior.
I like to use this simpler solution for names, where toUp is an array of full names split by (" "):
for (String name : toUp) {
result = result + Character.toUpperCase(name.charAt(0)) +
name.substring(1).toLowerCase() + " ";
}
And this modified solution could be used to uppercase only the first letter of a full String, again toUp is a list of strings:
for (String line : toUp) {
result = result + Character.toUpperCase(line.charAt(0)) +
line.substring(1).toLowerCase();
}
Hope this helps.
Are there any built in methods available to convert a string into Title Case format?
Apache Commons StringUtils.capitalize() or Commons Text WordUtils.capitalize()
e.g: WordUtils.capitalize("i am FINE") = "I Am FINE" from WordUtils doc
There are no capitalize() or titleCase() methods in Java's String class. You have two choices:
using commons lang string utils.
StringUtils.capitalize(null) = null
StringUtils.capitalize("") = ""
StringUtils.capitalize("cat") = "Cat"
StringUtils.capitalize("cAt") = "CAt"
StringUtils.capitalize("'cat'") = "'cat'"
write (yet another) static helper method toTitleCase()
Sample implementation
public static String toTitleCase(String input) {
StringBuilder titleCase = new StringBuilder(input.length());
boolean nextTitleCase = true;
for (char c : input.toCharArray()) {
if (Character.isSpaceChar(c)) {
nextTitleCase = true;
} else if (nextTitleCase) {
c = Character.toTitleCase(c);
nextTitleCase = false;
}
titleCase.append(c);
}
return titleCase.toString();
}
Testcase
System.out.println(toTitleCase("string"));
System.out.println(toTitleCase("another string"));
System.out.println(toTitleCase("YET ANOTHER STRING"));
outputs:
String
Another String
YET ANOTHER STRING
If I may submit my take on the solution...
The following method is based on the one that dfa posted. It makes the following major change (which is suited to the solution I needed at the time): it forces all characters in the input string into lower case unless it is immediately preceded by an "actionable delimiter" in which case the character is coerced into upper case.
A major limitation of my routine is that it makes the assumption that "title case" is uniformly defined for all locales and is represented by the same case conventions I have used and so it is less useful than dfa's code in that respect.
public static String toDisplayCase(String s) {
final String ACTIONABLE_DELIMITERS = " '-/"; // these cause the character following
// to be capitalized
StringBuilder sb = new StringBuilder();
boolean capNext = true;
for (char c : s.toCharArray()) {
c = (capNext)
? Character.toUpperCase(c)
: Character.toLowerCase(c);
sb.append(c);
capNext = (ACTIONABLE_DELIMITERS.indexOf((int) c) >= 0); // explicit cast not needed
}
return sb.toString();
}
TEST VALUES
a string
maRTin o'maLLEY
john wilkes-booth
YET ANOTHER STRING
OUTPUTS
A String
Martin O'Malley
John Wilkes-Booth
Yet Another String
Use WordUtils.capitalizeFully() from Apache Commons.
WordUtils.capitalizeFully(null) = null
WordUtils.capitalizeFully("") = ""
WordUtils.capitalizeFully("i am FINE") = "I Am Fine"
You can use apache commons langs like this :
WordUtils.capitalizeFully("this is a text to be capitalize")
you can find the java doc here :
WordUtils.capitalizeFully java doc
and if you want to remove the spaces in between the worlds you can use :
StringUtils.remove(WordUtils.capitalizeFully("this is a text to be capitalize")," ")
you can find the java doc for String
StringUtils.remove java doc
i hope this help.
If you want the correct answer according to the latest Unicode standard, you should use icu4j.
UCharacter.toTitleCase(Locale.US, "hello world", null, 0);
Note that this is locale sensitive.
Api Documentation
Implementation
Here's another take based on #dfa's and #scottb's answers that handles any non-letter/digit characters:
public final class TitleCase {
public static String toTitleCase(String input) {
StringBuilder titleCase = new StringBuilder(input.length());
boolean nextTitleCase = true;
for (char c : input.toLowerCase().toCharArray()) {
if (!Character.isLetterOrDigit(c)) {
nextTitleCase = true;
} else if (nextTitleCase) {
c = Character.toTitleCase(c);
nextTitleCase = false;
}
titleCase.append(c);
}
return titleCase.toString();
}
}
Given input:
MARY ÄNN O’CONNEŽ-ŠUSLIK
the output is
Mary Änn O’Connež-Šuslik
This is something I wrote to convert snake_case to lowerCamelCase but could easily be adjusted based on the requirements
private String convertToLowerCamel(String startingText)
{
String[] parts = startingText.split("_");
return parts[0].toLowerCase() + Arrays.stream(parts)
.skip(1)
.map(part -> part.substring(0, 1).toUpperCase() + part.substring(1).toLowerCase())
.collect(Collectors.joining());
}
Using Spring's StringUtils:
org.springframework.util.StringUtils.capitalize(someText);
If you're already using Spring anyway, this avoids bringing in another framework.
Use this method to convert a string to title case :
static String toTitleCase(String word) {
return Stream.of(word.split(" "))
.map(w -> w.toUpperCase().charAt(0)+ w.toLowerCase().substring(1))
.reduce((s, s2) -> s + " " + s2).orElse("");
}
I know this is older one, but doesn't carry the simple answer, I needed this method for my coding so I added here, simple to use.
public static String toTitleCase(String input) {
input = input.toLowerCase();
char c = input.charAt(0);
String s = new String("" + c);
String f = s.toUpperCase();
return f + input.substring(1);
}
you can very well use
org.apache.commons.lang.WordUtils
or
CaseFormat
from Google's API.
I had this problem and i searched for it
then i made my own method using some java keywords
just need to pass String variable as parameter and get output as proper titled String.
public class Main
{
public static void main (String[]args)
{
String st = "pARVeEN sISHOsIYA";
String mainn = getTitleCase (st);
System.out.println (mainn);
}
public static String getTitleCase(String input)
{
StringBuilder titleCase = new StringBuilder (input.length());
boolean hadSpace = false;
for (char c:input.toCharArray ()){
if(Character.isSpaceChar(c)){
hadSpace = true;
titleCase.append (c);
continue;
}
if(hadSpace){
hadSpace = false;
c = Character.toUpperCase(c);
titleCase.append (c);
}else{
c = Character.toLowerCase(c);
titleCase.append (c);
}
}
String temp=titleCase.toString ();
StringBuilder titleCase1 = new StringBuilder (temp.length ());
int num=1;
for (char c:temp.toCharArray ())
{ if(num==1)
c = Character.toUpperCase(c);
titleCase1.append (c);
num=0;
}
return titleCase1.toString ();
}
}
It seems none of the answers format it in the actual title case: "How to Land Your Dream Job", "To Kill a Mockingbird", etc. so I've made my own method. Works best for English languages texts.
private final static Set<Character> TITLE_CASE_DELIMITERS = new HashSet<>();
static {
TITLE_CASE_DELIMITERS.add(' ');
TITLE_CASE_DELIMITERS.add('.');
TITLE_CASE_DELIMITERS.add(',');
TITLE_CASE_DELIMITERS.add(';');
TITLE_CASE_DELIMITERS.add('/');
TITLE_CASE_DELIMITERS.add('-');
TITLE_CASE_DELIMITERS.add('(');
TITLE_CASE_DELIMITERS.add(')');
}
private final static Set<String> TITLE_SMALLCASED_WORDS = new HashSet<>();
static {
TITLE_SMALLCASED_WORDS.add("a");
TITLE_SMALLCASED_WORDS.add("an");
TITLE_SMALLCASED_WORDS.add("the");
TITLE_SMALLCASED_WORDS.add("for");
TITLE_SMALLCASED_WORDS.add("in");
TITLE_SMALLCASED_WORDS.add("on");
TITLE_SMALLCASED_WORDS.add("of");
TITLE_SMALLCASED_WORDS.add("and");
TITLE_SMALLCASED_WORDS.add("but");
TITLE_SMALLCASED_WORDS.add("or");
TITLE_SMALLCASED_WORDS.add("nor");
TITLE_SMALLCASED_WORDS.add("to");
}
public static String toCapitalizedWord(String oneWord) {
if (oneWord.length() < 1) {
return oneWord.toUpperCase();
}
return "" + Character.toTitleCase(oneWord.charAt(0)) + oneWord.substring(1).toLowerCase();
}
public static String toTitledWord(String oneWord) {
if (TITLE_SMALLCASED_WORDS.contains(oneWord.toLowerCase())) {
return oneWord.toLowerCase();
}
return toCapitalizedWord(oneWord);
}
public static String toTitleCase(String str) {
StringBuilder result = new StringBuilder();
StringBuilder oneWord = new StringBuilder();
char previousDelimiter = 'x';
/* on start, always move to upper case */
for (char c : str.toCharArray()) {
if (TITLE_CASE_DELIMITERS.contains(c)) {
if (previousDelimiter == '-' || previousDelimiter == 'x') {
result.append(toCapitalizedWord(oneWord.toString()));
} else {
result.append(toTitledWord(oneWord.toString()));
}
oneWord.setLength(0);
result.append(c);
previousDelimiter = c;
} else {
oneWord.append(c);
}
}
if (previousDelimiter == '-' || previousDelimiter == 'x') {
result.append(toCapitalizedWord(oneWord.toString()));
} else {
result.append(toTitledWord(oneWord.toString()));
}
return result.toString();
}
public static void main(String[] args) {
System.out.println(toTitleCase("one year in paris"));
System.out.println(toTitleCase("How to Land Your Dream Job"));
}
This is the simplest solution
static void title(String a,String b){
String ra = Character.toString(Character.toUpperCase(a.charAt(0)));
String rb = Character.toString(Character.toUpperCase(b.charAt(0)));
for(int i=1;i<a.length();i++){
ra+=a.charAt(i);
}
for(int i=1;i<b.length();i++){
rb+=b.charAt(i);
}
System.out.println(ra+" "+rb);
I recently ran into this problem too and unfortunately had many occurences of names beginning with Mc and Mac, I ended up using a version of scottb's code which I changed to handle these prefixes so it's here in case anyone wants to use it.
There are still edge cases which this misses but the worst thing that can happen is that a letter will be lower case when it should be capitalized.
/**
* Get a nicely formatted representation of the name.
* Don't send this the whole name at once, instead send it the components.<br>
* For example: andrew macnamara would be returned as:<br>
* Andrew Macnamara if processed as a single string<br>
* Andrew MacNamara if processed as 2 strings.
* #param name
* #return correctly formatted name
*/
public static String getNameTitleCase (String name) {
final String ACTIONABLE_DELIMITERS = " '-/";
StringBuilder sb = new StringBuilder();
if (name !=null && !name.isEmpty()){
boolean capitaliseNext = true;
for (char c : name.toCharArray()) {
c = (capitaliseNext)?Character.toUpperCase(c):Character.toLowerCase(c);
sb.append(c);
capitaliseNext = (ACTIONABLE_DELIMITERS.indexOf((int) c) >= 0);
}
name = sb.toString();
if (name.startsWith("Mc") && name.length() > 2 ) {
char c = name.charAt(2);
if (ACTIONABLE_DELIMITERS.indexOf((int) c) < 0) {
sb = new StringBuilder();
sb.append (name.substring(0,2));
sb.append (name.substring(2,3).toUpperCase());
sb.append (name.substring(3));
name=sb.toString();
}
} else if (name.startsWith("Mac") && name.length() > 3) {
char c = name.charAt(3);
if (ACTIONABLE_DELIMITERS.indexOf((int) c) < 0) {
sb = new StringBuilder();
sb.append (name.substring(0,3));
sb.append (name.substring(3,4).toUpperCase());
sb.append (name.substring(4));
name=sb.toString();
}
}
}
return name;
}
Conversion to Proper Title Case :
String s= "ThiS iS SomE Text";
String[] arr = s.split(" ");
s = "";
for (String s1 : arr) {
s += WordUtils.capitalize(s1.toLowerCase()) + " ";
}
s = s.substring(0, s.length() - 1);
Result : "This Is Some Text"
This converter transform any string containing camel case, white-spaces, digits and other characters to sanitized title case.
/**
* Convert a string to title case in java (with tests).
*
* #author Sudipto Chandra
*/
public abstract class TitleCase {
/**
* Returns the character type. <br>
* <br>
* Digit = 2 <br>
* Lower case alphabet = 0 <br>
* Uppercase case alphabet = 1 <br>
* All else = -1.
*
* #param ch
* #return
*/
private static int getCharType(char ch) {
if (Character.isLowerCase(ch)) {
return 0;
} else if (Character.isUpperCase(ch)) {
return 1;
} else if (Character.isDigit(ch)) {
return 2;
}
return -1;
}
/**
* Converts any given string in camel or snake case to title case.
* <br>
* It uses the method getCharType and ignore any character that falls in
* negative character type category. It separates two alphabets of not-equal
* cases with a space. It accepts numbers and append it to the currently
* running group, and puts a space at the end.
* <br>
* If the result is empty after the operations, original string is returned.
*
* #param text the text to be converted.
* #return a title cased string
*/
public static String titleCase(String text) {
if (text == null || text.length() == 0) {
return text;
}
char[] str = text.toCharArray();
StringBuilder sb = new StringBuilder();
boolean capRepeated = false;
for (int i = 0, prev = -1, next; i < str.length; ++i, prev = next) {
next = getCharType(str[i]);
// trace consecutive capital cases
if (prev == 1 && next == 1) {
capRepeated = true;
} else if (next != 0) {
capRepeated = false;
}
// next is ignorable
if (next == -1) {
// System.out.printf("case 0, %d %d %s\n", prev, next, sb.toString());
continue; // does not append anything
}
// prev and next are of same type
if (prev == next) {
sb.append(str[i]);
// System.out.printf("case 1, %d %d %s\n", prev, next, sb.toString());
continue;
}
// next is not an alphabet
if (next == 2) {
sb.append(str[i]);
// System.out.printf("case 2, %d %d %s\n", prev, next, sb.toString());
continue;
}
// next is an alphabet, prev was not +
// next is uppercase and prev was lowercase
if (prev == -1 || prev == 2 || prev == 0) {
if (sb.length() != 0) {
sb.append(' ');
}
sb.append(Character.toUpperCase(str[i]));
// System.out.printf("case 3, %d %d %s\n", prev, next, sb.toString());
continue;
}
// next is lowercase and prev was uppercase
if (prev == 1) {
if (capRepeated) {
sb.insert(sb.length() - 1, ' ');
capRepeated = false;
}
sb.append(str[i]);
// System.out.printf("case 4, %d %d %s\n", prev, next, sb.toString());
}
}
String output = sb.toString().trim();
output = (output.length() == 0) ? text : output;
//return output;
// Capitalize all words (Optional)
String[] result = output.split(" ");
for (int i = 0; i < result.length; ++i) {
result[i] = result[i].charAt(0) + result[i].substring(1).toLowerCase();
}
output = String.join(" ", result);
return output;
}
/**
* Test method for the titleCase() function.
*/
public static void testTitleCase() {
System.out.println("--------------- Title Case Tests --------------------");
String[][] samples = {
{null, null},
{"", ""},
{"a", "A"},
{"aa", "Aa"},
{"aaa", "Aaa"},
{"aC", "A C"},
{"AC", "Ac"},
{"aCa", "A Ca"},
{"ACa", "A Ca"},
{"aCamel", "A Camel"},
{"anCamel", "An Camel"},
{"CamelCase", "Camel Case"},
{"camelCase", "Camel Case"},
{"snake_case", "Snake Case"},
{"toCamelCaseString", "To Camel Case String"},
{"toCAMELCase", "To Camel Case"},
{"_under_the_scoreCamelWith_", "Under The Score Camel With"},
{"ABDTest", "Abd Test"},
{"title123Case", "Title123 Case"},
{"expect11", "Expect11"},
{"all0verMe3", "All0 Ver Me3"},
{"___", "___"},
{"__a__", "A"},
{"_A_b_c____aa", "A B C Aa"},
{"_get$It132done", "Get It132 Done"},
{"_122_", "122"},
{"_no112", "No112"},
{"Case-13title", "Case13 Title"},
{"-no-allow-", "No Allow"},
{"_paren-_-allow--not!", "Paren Allow Not"},
{"Other.Allow.--False?", "Other Allow False"},
{"$39$ldl%LK3$lk_389$klnsl-32489 3 42034 ", "39 Ldl Lk3 Lk389 Klnsl32489342034"},
{"tHis will BE MY EXAMple", "T His Will Be My Exa Mple"},
{"stripEvery.damn-paren- -_now", "Strip Every Damn Paren Now"},
{"getMe", "Get Me"},
{"whatSthePoint", "What Sthe Point"},
{"n0pe_aLoud", "N0 Pe A Loud"},
{"canHave SpacesThere", "Can Have Spaces There"},
{" why_underScore exists ", "Why Under Score Exists"},
{"small-to-be-seen", "Small To Be Seen"},
{"toCAMELCase", "To Camel Case"},
{"_under_the_scoreCamelWith_", "Under The Score Camel With"},
{"last one onTheList", "Last One On The List"}
};
int pass = 0;
for (String[] inp : samples) {
String out = titleCase(inp[0]);
//String out = WordUtils.capitalizeFully(inp[0]);
System.out.printf("TEST '%s'\nWANTS '%s'\nFOUND '%s'\n", inp[0], inp[1], out);
boolean passed = (out == null ? inp[1] == null : out.equals(inp[1]));
pass += passed ? 1 : 0;
System.out.println(passed ? "-- PASS --" : "!! FAIL !!");
System.out.println();
}
System.out.printf("\n%d Passed, %d Failed.\n", pass, samples.length - pass);
}
public static void main(String[] args) {
// run tests
testTitleCase();
}
}
Here are some inputs:
aCamel
TitleCase
snake_case
fromCamelCASEString
ABCTest
expect11
_paren-_-allow--not!
why_underScore exists
last one onTheList
And my outputs:
A Camel
Title Case
Snake Case
From Camel Case String
Abc Test
Expect11
Paren Allow Not
Why Under Score Exists
Last One On The List
Without dependency -
public static String capitalizeFirstLetter(String s) {
if(s.trim().length()>0){
return s.substring(0, 1).toUpperCase() + s.substring(1);
}
return s;
}
public static String createTitleCase(String s) {
if(s.trim().length()>0){
final StringBuilder sb = new StringBuilder();
String[] strArr = s.split("\\s*");
for(String s1 : strArr) {
sb.append(capitalizeFirstLetter(s1));
}
s = sb.toString();
sb.setLength(0);
}
return s;
}
This should work:
String str="i like pancakes";
String arr[]=str.split(" ");
String strNew="";
for(String str1:arr)
{
Character oldchar=str1.charAt(0);
Character newchar=Character.toUpperCase(str1.charAt(0));
strNew=strNew+str1.replace(oldchar,newchar)+" ";
}
System.out.println(strNew);
The simplest way of converting any string into a title case, is to use googles package org.apache.commons.lang.WordUtils
System.out.println(WordUtils.capitalizeFully("tHis will BE MY EXAMple"));
Will result this
This Will Be My Example
I'm not sure why its named "capitalizeFully", where in fact the function is not doing a full capital result, but anyways, thats the tool that we need.
Sorry I am a beginner so my coding habit sucks!
public class TitleCase {
String title(String sent)
{
sent =sent.trim();
sent = sent.toLowerCase();
String[] str1=new String[sent.length()];
for(int k=0;k<=str1.length-1;k++){
str1[k]=sent.charAt(k)+"";
}
for(int i=0;i<=sent.length()-1;i++){
if(i==0){
String s= sent.charAt(i)+"";
str1[i]=s.toUpperCase();
}
if(str1[i].equals(" ")){
String s= sent.charAt(i+1)+"";
str1[i+1]=s.toUpperCase();
}
System.out.print(str1[i]);
}
return "";
}
public static void main(String[] args) {
TitleCase a = new TitleCase();
System.out.println(a.title(" enter your Statement!"));
}
}