I have a String:
String example = "AA5DD2EE3MM";
I want to replace the number with the number of spaces. Example:
String example = "AA DD EE MM"
If the String would be
String anotherExample = "a3ee"
It should turn into:
String anotherExample = "a ee"
I want to do it for any string. Not only for the examples above.
Split your input at digit and non digit chars as a stream, map digits to the corsponding number of spaces using String.repeat, collect to string using Collectors.joining():
String input = "AA5DD2EE3MM";
String regex = "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)";
String result = Pattern.compile(regex)
.splitAsStream(input)
.map(s -> s.matches("\\d+") ? " ".repeat(Integer.parseInt(s)) : s)
.collect(Collectors.joining());
You could also use this approach, which is simpler but also far less elegant:
String example = "a4aa";
String newString = "";
for (int i = 0; i < example.length(); i++) {
if (Character.isDigit(example.charAt(i))) {
for (int a = 0; a < Character.getNumericValue(example.charAt(i)); a++) {
newString += " ";
}
} else {
newString += example.charAt(i);
}
}
System.out.println(newString);
Using a pattern matcher approach:
String input = "AA5DD2EE3MM";
Pattern pattern = Pattern.compile("\\d+");
Matcher m = pattern.matcher(input);
StringBuffer buffer = new StringBuffer();
while (m.find()) {
m.appendReplacement(buffer,new String(new char[Integer.valueOf(m.group())]).replace("\0", " "));
}
m.appendTail(buffer);
System.out.println(buffer.toString()); // AA DD EE MM
The idea here is to iterate the string, pausing at each digit match. We replace each digit with space replicated the same number of times as the digit.
public static String replaceDigitsWithSpaces(String input) {
String result = "";
int len = input.length(), i =0;
while( i < len) {
if(Character.isLetter(input.charAt(i))) {
result += input.charAt(i);
}else if(Character.isDigit(input.charAt(i))) {
//generate number upto characters
int k = 0, j = i;
String temp = "";
while(j < len) {
if(Character.isDigit(input.charAt(j))) {
temp += input.charAt(j);
j++;
}else {
break;
}
}
k = Integer.parseInt(temp);
while(k != 0) {
result+= " ";
k--;
}
i = j;
continue;
}
i++;
}
return result;
}
input:: "AA23BB1C11C8"<br>
output:: AA BB C C .
StringBuilder is more efficient for concatenation:
public static String spaceIt(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
for (int j = 0; j < Character.digit(c, 10); j++) {
sb.append(' ');
}
} else {
sb.append(c);
}
}
return sb.toString();
}
Related
I am trying to split a String with a Last space of my max allowed character:
Expectation:
String name = "John David Guetta MarkHenry Anthoney Sam";
Max Character allowed : 30
So it should return as:
John David Guetta MarkHenry
Anthoney Sam
Actual Result:
John David Guetta MarkHenry An
thoney Sam
Code:
public static List<String> splitByLength(String str, int n) {
List<String> returnList = new ArrayList<>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if (i > 0 && (i % n == 0)) {
returnList.add(sb.toString());
sb = new StringBuilder();
}
sb.append(str.charAt(i));
}
if (StringUtils.isNoneBlank(sb.toString())) {
returnList.add(sb.toString());
}
return returnList;
}
You could use a regex that accepts up to 30 characters:
String name = "John David Guetta MarkHenry Anthoney Sam";
Pattern p = Pattern.compile(".{1,30}(\\s+|$)");
Matcher m = p.matcher(name);
while(m.find()) {
System.out.println(m.group().trim());
}
Note the (\\s|$) to break either on a space or once the end of the initial string is reached.
I always find it difficult and troublesome using Regex, so here is a solution that I would use
private static void splitByLength(String str, int n) {
String newStr = "";
int splitIndex = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) != ' ') {
newStr = newStr + str.charAt(i); //Keep adding chars until you find a space
if (newStr.length() > n) { //If newStr's length exceeds 'n', break the loop
break;
}
} else {
splitIndex = i; //Store the last space index
newStr = newStr + ' ';
}
}
System.out.println(str.substring(0, splitIndex).trim()); //Use the splitIndex to print a substring
System.out.println(str.substring(splitIndex, str.length()).trim());
}
Given a string in Java, how can I obtain a new string where all adjacent sequences of digits are reversed?
My code:
import static java.lang.System.*;
public class P2
{
public static void main(String[] args)
{
if(args.length < 1)
{
err.printf("Usage: java -ea P2 String [...]\n");
exit(1);
}
String[] norm = new String[args.length];
for(int i = 0; i<norm.length;i++)
{
norm[i] = args[i];
}
}
public String invertDigits(String[] norm)
{
}
}
And as an example, this is what it should do:
Inputs: 1234 abc9876cba a123 312asd a12b34c56d
1234 -> 4321
abc9876cba -> abc6789cba
a123 -> a321
312asd -> 213asd
a12b34c56d -> a21b43c65d
Although the question is heavily downvoted, the proposed problem seems clear now. I chose to solve it using a regular expression match in a recursive function.
private static String reverseDigits(String s) {
// the pattern will match a sequence of 1 or more digits
Matcher matcher = Pattern.compile("\\d+").matcher(s);
// fetch the position of the next sequence of digits
if (!matcher.find()) {
return s; // no more digits
}
// keep everything before the number
String pre = s.substring(0, matcher.start());
// take the number and reverse it
String number = matcher.group();
number = new StringBuilder(number).reverse().toString();
// continue with the rest of the string, then concat!
return pre + number + reverseDigits(s.substring(matcher.end()));
}
And here's the iterative approach.
private static String reverseDigits(String s) {
//if (s.isEmpty()) return s;
String res = "";
int base = 0;
Matcher matcher = Pattern.compile("\\d+").matcher(s);
while (!matcher.hitEnd()) {
if (!matcher.find()) {
return res + s.substring(base);
}
String pre = s.substring(base, matcher.start());
base = matcher.end();
String number = matcher.group();
number = new StringBuilder(number).reverse().toString();
res += pre + number;
}
return res;
}
String str = "1234";
//indexes
int i = 0, j = str.length()-1;
// find digits (if any)
while (!Character.isDigit(str.charAt(i)) && i < str.length()) {
i++;
}
while (!Character.isDigit(str.charAt(j)) && j >= 0) {
j--;
}
// while we havent searched all the digits
while (i < j) {
// switch digits
str = str.substring(0, i) + str.charAt(j) + str.substring(i + 1, j) + str.charAt(i) + str.substring(j + 1);
i++;
j--;
// find the next digits
while (!Character.isDigit(str.charAt(i)) && i < str.length()) {
i++;
}
while (!Character.isDigit(str.charAt(j)) && j >= 0) {
j--;
}
}
System.out.println(str);
Another dynamic approach without using regex classes:
public static String reverseOnlyNumbers(String s) {
StringBuilder digits = new StringBuilder();
StringBuilder result = new StringBuilder();
boolean start = false;
for (int i = 0; i < s.length(); i++) {
Character c = s.charAt(i);
if (Character.isDigit(c)) {
start = true;
digits.append(c);
}else {
start = false;
if (digits.length() > 0) {
result.append(digits.reverse().toString());
digits = new StringBuilder();
}
result.append(c);
}
}
return start ? result.append(digits.reverse()).toString() : result.toString();
}
This may sound like a very simple question but how do you remove multiple different characters from a string without having to write a line for each, which is what I have laboriously done. I have written a string example below:
String word = "Hello, t-his is; an- (example) line."
word = word.replace(",", "");
word = word.replace(".", "");
word = word.replace(";", "");
word = word.replace("-", "");
word = word.replace("(", "");
word = word.replace(")", "");
System.out.println(word);
Which would produce "Hello this is an example line". A more efficient way is?
Use
word = word.replaceAll("[,.;\\-()]", "");
Note that special character - (hyphen) should be escaped by double backslashes, because otherwise it is considered to construct a range.
Although no more efficient than the original replace technique you could use
word = word.replaceAll("\\p{Punct}+", "");
to use a simple expression using replaceAll with a wider range of characters replaced
Without (ab)using regex, I would do that way:
String word = "Hello, t-his is; an- (example) line.";
String undesirable = ",.;-()";
int len1 = undesirable.length();
int len2 = word.length();
StringBuilder sb = new StringBuilder(len2);
outer: for (int j = 0; j < len2; j++) {
char c = word.charAt(j);
for (int i = 0; i < len; i++) {
if (c == undesirable.charAt(i)) continue outer;
}
sb.append(c);
}
System.out.println(sb.toString());
The advantage is performance. You don't need the overhead of creating and parsing a regular expression.
You could encapsulate that in a method:
public static String removeCharacters(String word, String undesirable) {
int len1 = undesirable.length();
int len2 = word.length();
StringBuilder sb = new StringBuilder(len2);
outer: for (int j = 0; j < len2; j++) {
char c = word.charAt(j);
for (int i = 0; i < len1; i++) {
if (c == undesirable.charAt(i)) continue outer;
}
sb.append(c);
}
return sb.toString();
}
public static String removeSpecialCharacters(String word) {
return removeCharacters(word, ",.;-()");
}
And then, you would use it this way:
public static void testMethod() {
String word = "Hello, t-his is; an- (example) line.";
System.out.println(removeSpecialCharacters(word));
}
Here is a performance test:
public class WordTest {
public static void main(String[] args) {
int iterations = 10000000;
long t1 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
testAsArray();
}
long t2 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
testRegex();
}
long t3 = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
testAsString();
}
long t4 = System.currentTimeMillis();
System.out.println("Without regex, but using copied arrays: " + (t2 - t1));
System.out.println("With precompiled regex: " + (t3 - t2));
System.out.println("Without regex, but using string: " + (t4 - t3));
}
public static void testAsArray() {
String word = "Hello, t-his is; an- (example) line.";
char[] undesirable = ",.;-()".toCharArray();
StringBuilder sb = new StringBuilder(word.length());
outer: for (char c : word.toCharArray()) {
for (char h : undesirable) {
if (c == h) continue outer;
}
sb.append(c);
}
sb.toString();
}
public static void testAsString() {
String word = "Hello, t-his is; an- (example) line.";
String undesirable = ",.;-()";
int len1 = undesirable.length();
int len2 = word.length();
StringBuilder sb = new StringBuilder(len2);
outer: for (int j = 0; j < len2; j++) {
char c = word.charAt(j);
for (int i = 0; i < len1; i++) {
if (c == undesirable.charAt(i)) continue outer;
}
sb.append(c);
}
sb.toString();
}
private static final Pattern regex = Pattern.compile("[,\\.;\\-\\(\\)]");
public static void testRegex() {
String word = "Hello, t-his is; an- (example) line.";
String result = regex.matcher(word).replaceAll("");
}
}
The output on my machine:
Without regex, but using copied arrays: 5880
With precompiled regex: 11011
Without regex, but using string: 3844
Here is a solution to do this with minimal effort; the toRemove string contains all character you don't want to see in the output:
public static String removeChars(final String input, final String toRemove)
{
final StringBuilder sb = new StringBuilder(input.length());
final CharBuffer buf = CharBuffer.wrap(input);
char c;
while (buf.hasRemaining()) {
c = buf.get();
if (toRemove.indexOf(c) == -1)
sb.append(c);
}
return sb.toString();
}
If you use Java 8 you can even use this (unfortunately there's no CharStream so the casts are necessary...):
public static String removeChars(final String input, final String toRemove)
{
final StringBuilder sb = new StringBuilder(input.length());
input.chars().filter(c -> toRemove.indexOf((char) c) == -1)
.forEach(i -> sb.append((char) i));
return sb.toString();
}
You could try using a regular expression with Java's String.replaceAll method:
word = word.replaceAll(",|\.|;|-|\(|\)", "");
If you're not familiar with regular expressions, | means "or". So we are essentially saying , or . or ; or - or ( or ).
See more: Java documentation for String.replaceAll
Edit:
As mentioned, my previous version will not compile. Just for the sake of correctness (even though it has been pointed out that this is not the optimal solution), here is the corrected version of my regex:
word = word.replaceAll(",|\\.|;|-|\\(|\\)", "");
I was asked to replace the first 5 characters in any sentence inputted in JOptionPane, with asterisks. So I have this...
import javax.swing.*;
public class Option {
public static void main (String[] args) {
String myName;
myName= JOptionPane.showInputDialog("Input a sentence");
System.out.println(myName.substring
I just can't figure out how to isolate the first 5 characters in any sentence with spaces. Any help or hints on this would be great
You can use regex, like this:
myName = myName.replaceFirst(".{5}", "*****");
.{5} is regex and means five characters.
EDIT: Since you needed to distinguish white spaces:
String tmp;
int lastCharIndex;
while(int i < 5) {
if (!Character.isWhiteSpace(string.charAt(i)) {
tmp += *
i++;
} else {
tmp += " ";
}
lastCharIndex++;
}
tmp += myName.substring(lastCharIndex);
This solution is a bit longer but doesn't replace spaces with asterisks:
import javax.swing.*;
public class Option {
public static void main (String[] args) {
String myName;
myName= JOptionPane.showInputDialog("Input a sentence");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
if(myName.charAt(i) != " ") {
sb.append('*');
}
else sb.append(' ');
}
System.out.println(sb.toString() + myName.subString(5));
}
}
It's more simple and fast if you use a loop for replace the desired characters. e.g.:
String input = "Hey how are you";
char[] chars = input.toCharArray();
for (int i = 0, j = 0; i < chars.length && j < 5; i++) {
char ch = chars[i];
if (!Character.isWhitespace(ch)) {
chars[i] = '*';
j++;
}
}
String output = new String(chars);
System.out.println(output);
Output:
*** **w are you
Character.isWhiteSpace()
This is a good method to use
String s = "Hi I am good";
String newString = "";
int count = 0
int i = 0;
while(count < 5){
if (!Character.isWhiteSpace(s.charAt(i)) {
newString += '*';
count++;
i++;
} else {
newString += string.charAt(i);
i++;
}
}
for (int i = count; i < s.length; i++) {
newString += string.charAt(i);
}
System.out.println(newString);
// ** * ** good
You could always implement a simple for loop with a condition inside like this:
int charCount = 0;
for(int i = 0; i < myName.length(); i++){
if(myName.charAt(i) != ' '){
myName = '*" + myName.subString(i);
charCount++;
}
if(charCount == 5)
break;
}
I am attempting to split the components of a string into an array, so that they can be accessed more easily.
For example: 4+5= should become ['4','+','5','='].
Edit: -
I would need consecutive numbers to be joined together, and whitespaces can be ignored. Thanks again!
You can solve it with regex lookaround mechanism.
String str = "10 * 10 - 40 + 100/2 = 110";
//but first lets remove white spaces (it will makes regex easier)
String strWithoutSpaces=str.replaceAll("\\s+", "");
String[] tokens = strWithoutSpaces.split("(?<=[-+*/=])|(?=[-+*/=])");
for (String t:tokens)
System.out.print(t+",");
Output:
10,*,10,-,40,+,100,/,2,=,110,
You can use
String str = "4+5=";
String[] tokens = str.split("(?!^)");
for (String s : tokens) {
System.out.println(s);
}
This will output
4
+
5
=
You could use toCharArray() method
String s ="4+5=";
char [] stArr = s.toCharArray();
for(char ss: stArr){
System.out.println(ss);
}
Out put
4
+
5
=
You could do something like this:
public static void main(String args[]) {
String str = "45+5-26";
String strArr[] = new String[str.length()];
StringBuffer sb = new StringBuffer();
int cnt = 0;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch != '\0') {
if (ch == ' ') {
continue;
}
if (ch >= 48 && ch <= 57) {
sb.append(ch);
continue;
} else {
strArr[cnt++] = sb.toString();
sb = new StringBuffer();
// sb.append(ch);
}
strArr[cnt++] = ch + "";
sb = new StringBuffer();
}
}
strArr[cnt++] = sb.toString();
sb = new StringBuffer();
System.out.println("strArray: ");
for (int i = 0; i < strArr.length; i++) {
if (strArr[i] == null)
break;
System.out.println(strArr[i]);
}
}
If you have only operators as the separator between the numbers this would be more easy to get the string tokens.
You can modify as below if you want the tokens separated by a comma:
for (int i = 0; i < strArr.length; i++) {
if (strArr[i] == null)
break;
// System.out.println(strArr[i]);
if(i!=0)
sbResult.append(",");
sbResult.append(strArr[i]);
}
System.out.println("sbResult: "+sbResult.toString());