My code is as below. i need to add single quotes for each word in string with single quotes after appending DD to it.
public class Main
{
public static void main(String[] args) {
String ChkboxIds = "'a1b2c3','321cba','123abc'";
String checkBoxId = null;
String checkId = null;
StringBuilder checkIDS = new StringBuilder("'");
for(int i=0;i<=ChkboxIds.split(ChkboxIds, ',').length;i++){
checkBoxId = "DD"+ChkboxIds.split(",")[i].replace("'","")+","+checkBoxId;
checkId = checkBoxId.substring(0, checkBoxId.length() - 5);
System.out.println("---PRINT---"+checkId);
for(int j=0;j<i;j++){
checkIDS..append('\'').append(checkId.split(",")).append('\'').append(',');
System.out.println("---PRINT123----"+checkIDS);
}
}
}
}
I have tried using StringBuffer too. please point your answers here. The output i get is some junk data while i need the words with dd attached at the start.
Expected output:'DDa1b2c3','DD321cba','DD123abc'
Problem
issue at .append(checkId.split(",")) where you append an String[] so it's representation is it's hashcode
don't need a second loop, each word need one loop round, no inner loop needed
your split is wrong, you need ChkboxIds.split(","), you don't need with the same string as delimiter
Fix
You can do much more simpler than that
split on comma
remove quotes, append DD, add quotes
save at same place in array
join array with comma
String chkboxIds = "'a1b2c3','321cba','123abc'";
String[] splitted = chkboxIds.split(",");
String checkBoxId;
for (int i = 0; i < splitted.length; i++) {
checkBoxId = "DD" + splitted[i].replace("'", "");
splitted[i] = "'" + checkBoxId + "'";
}
String result = String.join(",", splitted);
System.out.println(result);
// 'DDa1b2c3','DD321cba','DD123abc'
Regex power
String chkboxIds = "'a1b2c3','321cba','123abc'";
String result = chkboxIds.replaceAll("'(\\w+)'", "'DD$1'");
Try this:
var ids = Arrays.stream( ChkboxIds.split( "," ) ) // Separate the words
.map( s -> s.replace( '\'', '' ) ) // Strip the single quotes
.map( s -> "DD%s".formatted( s ) ) // Prepend with "DD"
.collect( Collectors.joining( "','", "'", "'" ) );
System.out.println( ids );
Alternatively:
var ids = Arrays.stream( ChkboxIds.split( "," ) ) // Separate the words
.map( s -> s.replaceFirst( "'", "'DD" ) ) // Replace the first single quote with the prefix
.collect( Collectors.joining( "," ) );
System.out.println( ids );
Refer to the respective Javadoc for the details.
For a simpler solution, you can try the code below.
public class Main
{
public static void main(String[] args) {
String ChkboxIds = "'a1b2c3','321cba','123abc'";
//Replace all single quotes from the ChkboxIds, split them using comma delimiter, and store it to variable array
String[] ChkboxIdsNew = ChkboxIds.replace("'","").split(",");
String checkIDS = ""; //String variable to be used to store the check ids
//Loop through the ChkboxIdsNew array
for (int i = 0; i < ChkboxIdsNew.length; i++) {
//Only append comma if i is greater than zero
if (i > 0) {
checkIDS = checkIDS + ",";
}
//Concatenate the single quotes and prefix DD then append it to checkIDS
checkIDS = checkIDS + "'DD" + ChkboxIdsNew[i] + "'";
}
System.out.println(checkIDS);
}
}
Output:
Using regular expressions:
If the single words doesnt contain additional single quotes:
String ChkboxIds = "'a1b2c3','321cba','123abc'";
ChkboxIds = ChkboxIds.replaceAll(",'",",'DD").replaceAll("^'","'DD");
Using iteration :
String arChkBoxIds[]= ChkboxIds.split(",");
StringBuilder checkIDS1 = new StringBuilder("");
for (String chkBoxId:arChkBoxIds){
checkIDS1.append("'DD").append(chkBoxId.substring(1)).append(",");
}
checkIDS1.setLength(checkIDS1.length()-1);
System.out.println(checkIDS1);
Related
I've been struggling to figure out how to get a word, of unknown length, from a string, of unknown length, that I'm reading from a file. The words I want from the string are always separated by "." and/or "&" with the whole string being surrounded by quotes. EX: ".Word.Characters&Numeric&Letters.Typos&Mistypes." I know the location of each "." and "&" as well as how many times they occur.
I want to feed the words into an array Example[i][j] based on whether or not the words are separated by a "." or a "&". So words contained between "." would be set into the i column of the array and words linked by "&" into the j rows of the array.
The input string can contain a largely variable number of words. Meaning that there can be only one word of interest, or one hundred+.
I'd prefer to use arrays to solve this problem. From what I've read regex would be slow, but work. split() may also work, but I think I'd have to know what words to look for before hand.
From this String: ".Word.Characters&Numeric&Letters.Typos&Mistypes." I'd expect to get: (without worrying about which is a row or column)
[[Word],[null],[null]],
[[Characters],[Numbers],[Letters]],
[[Typos],[Mistypes],[null]]
From this String ".Alpha.Beta.Zeta&Iota." I'd expect to get:
[[Alpha],[null]],
[[Beta],[null]],
[[Zeta],[Iota]]
//NumerOfPeriods tells me how many word "sections" are in the string
//Stor[] is an array that holds the string index locations of "."
for(int i=0;i<NumberOfPeriods;i++)
{
int length = Stor[i];
while(Line.charAt(length) != '"')
{
length++;
}
Example[i] = Line.substring(Stor[i], length);
}
//This code can get the words separated by "." but not by "&"
//Stor[] is an array that holds all string index locations of '.'
//AmpStor[] is an array that holds all string index locations of '&'
int TotalLength = Stor[0];
int InnerLength = 0;
int OuterLength = 0;
while(Line.charAt(TotalLength) != '"')
{
while(Line.charAt(OuterLength)!='.')
{
while(Line.charAt(InnerLength)!='&')
{
InnerLength++;
}
if(Stor[i] > AmpStor[i])
{
Example[i][j] = Line.substring(Stor[i], InnerLength);
}
if(Stor[i] < AmpStor[i])
{
Example[i][j] = Line.substring(AmpStor[i],InnerLength);
}
OuterLength++;
}
}
//Here I run into the issue of indexing into different parts of the array i & j
This is how I would solve your problem (it's completely different from your code but it works).
First of all, remove the quotes and the leading and trailing non-word characters. This can be done using replaceAll:
String Formatted = Line.replaceAll( "(^\"[.&]*)|([.&]*\"$)", "" );
The regular expression in the first argument will match the double quotes at both ends and the leading and trailing .s and &s. The method will return a new string where the matched characters are removed, because the second argument is an empty string (it replaces with an empty string).
Now you can split this string at each . using the split method. You could only define your output array after this call:
String[] StringGroups = Formatted.split( "\\." );
String[][] Elements = new String[StringGroups.length][];
Use an escaped backslash (\\) before the point to indicate that it should split on .-characters, since this method takes in a regular expression (and just . splits on any non-newline character).
Now split each string in that array at each & using the same split method. Add the result directly to your Elements array:
// Loop over the array
int MaxLength = 0;
for( int i = 0; i < StringGroups.length; i ++ ) {
String StrGroup = StringGroups[ i ];
String[] Group = StrGroup.split( "&" );
Elements[ i ] = Group;
// Measure the max length
if( Group.length > MaxLength ) {
MaxLength = Group.length;
}
}
A \\ is not necessary for the input, since & just matches &-characters. Now you only have to fill in your data into an array. The MaxLength variable is for adding the null values to your array. If you don't want them, just remove them and you're done here.
If you want the null values however, loop over your elements array and copy the current rows into new arrays:
for( int i = 0; i < Elements.length; i ++ ) {
String[] Current = Elements[ i ];
String[] New = new String[ MaxLength ];
// Copy existing values into new array, extra values remain null
System.arraycopy( Current, 0, New, 0, Current.length );
Elements[ i ] = New;
}
Now, the Elements array contains exactly what you wanted.
Here is the complete executable code:
public class StringSplitterExample {
public static void main( String[] args ) {
test( "\".Word.Characters&Numeric&Letters.Typos&Mistypes.\"" );
System.out.println(); // Line between
test( "\".Alpha.Beta.Zeta&Iota.\"" );
}
public static void test( String Line ) {
String Formatted = Line.replaceAll( "(^\"[.&]*)|([.&]*\"$)", "" );
String[] StringGroups = Formatted.split( "\\." );
String[][] Elements = new String[StringGroups.length][];
// Loop over the array
int MaxLength = 0;
for( int i = 0; i < StringGroups.length; i ++ ) {
String StrGroup = StringGroups[ i ];
String[] Group = StrGroup.split( "&" );
Elements[ i ] = Group;
// Measure the max length
if( Group.length > MaxLength ) {
MaxLength = Group.length;
}
}
for( int i = 0; i < Elements.length; i ++ ) {
String[] Current = Elements[ i ];
String[] New = new String[ MaxLength ];
// Copy existing values into new array, extra values remain null
System.arraycopy( Current, 0, New, 0, Current.length );
Elements[ i ] = New;
}
for( String[] Group : Elements ) {
for( String String : Group ) {
System.out.print( String );
System.out.print( " " );
}
System.out.println();
}
}
}
The output of this example:
Word null null
Characters Numeric Letters
Typos Mistypes null
Alpha null
Beta null
Zeta Iota
So this works, and you don't even need to know where the . and & characters are in your string. Java will just do that for you.
If I understand the problem correctly, you want to separate the string into substrings delimited by '.' and then for each of the substrings, separate it into subsubstrings delimited by '&'. If that's the case, then I would use the split method:
List<List<String>> terms = Arrays.stream(input.split("\\."))
.map(s -> Arrays.asList(s.split("\\&"))
.collect(Collectors.toList());
if you really need it to be returned as a null-padded array:
String[][] result = new String[terms.size()][ terms.stream.mapToInt(List::size).max().getAsInt()];
IntStream.range(0, terms.size()).forEach(i ->
IntStream.range(0, terms.get(i).size()).forEach(j ->
result[i][j] = terms.get(i).get(j)));
Here is how I tried to solve the problem:
import java.util.*;
import java.util.stream.*;
public class StringSplitSplits {
private static final String S1 = ".Word.Characters&Numeric&Letters.Typos&Mistypes.";
private static final String S2 = ".Alpha.Beta.Zeta&Iota.";
public static void main(String [] args) {
String str = stripStartAndEndDots(S1);
String [] ss = str.split("\\.");
int maxLength = getMaxLength(ss);
String [][] sss = Stream.of(ss)
.map(s -> s.split("&"))
.map(s -> Arrays.copyOf(s, maxLength))
.toArray(String[][]::new);
Stream.of(sss).forEach(s -> System.out.println(Arrays.toString(s)));
}
private static String stripStartAndEndDots(String input) {
if (input.startsWith(".")) {
input = input.substring(1);
}
if (input.endsWith(".")) {
input = input.substring(0, input.length()-1);
}
return input;
}
/*
* Get max length of the arrays split on the "&" for each
* string element of the input string array.
*/
private static int getMaxLength(String [] input) {
return Stream.of(input)
.map(s -> s.split("&"))
.mapToInt(ss -> ss.length)
.max()
.orElse(0);
}
}
Input: ".Word.Characters&Numeric&Letters.Typos&Mistypes."
Output:
[Word, null, null]
[Characters, Numeric, Letters]
[Typos, Mistypes, null]
Input: ".Alpha.Beta.Zeta&Iota."
Output:
[Alpha, null]
[Beta, null]
[Zeta, Iota]
I try to split
"11020199,Abc Germany ,aduz,,444,bieb,dc,2 ,2222.00,whatever 5dc,222.22,22.00,""98,00"",""12,00"",21-09-2018,06:00 "
It has double quotation only when theres a comma in the string, otherwise its seperated by just the comma and theres no double quotation.
How do i split this line properly? I've seen how to split it when everything is double quotated but not when its only done when theres a comma.
A simple example solution could be this, which takes care of the comma in double quoted values being kept:
Split the String by comma first and use the double quotes in order to merge their values afterwards:
public class SplitAndKeepQuotedValuesCommas {
public static void main(String[] args) {
String source = "11020199,Abc Germany ,aduz,,444,bieb,dc,2 ,2222.00,whatever 5dc,222.22,22.00,\"\"98,00\"\",\"\"12,00\"\",21-09-2018,06:00";
// split the String by comma
String[] justValues = source.split(",");
// print all items in the result
for (String s : justValues) {
System.out.println(s);
}
// prepare a List for all the values
List<String> resultList = new ArrayList<String>();
// then go through the values
for (int i = 0; i < justValues.length; i++) {
// and check if there is a String that begins with double double quotes
if (justValues[i].startsWith("\"\"")) {
/*
* if there is one, remove the double quotes from it and its successor,
* then concatenate them with a comma in between and add the result to the list
*/
String merged = justValues[i].replace("\"\"", "") + "," + justValues[i + 1].replace("\"\"", "");
resultList.add(merged);
/*
* since there are still values with trailing double double quotes,
* only add values without because they have already been added inside the merged value
*/
} else if (!justValues[i].endsWith("\"\"")) {
resultList.add(justValues[i]);
}
}
resultList.forEach(value -> {
System.out.println(value);
});
}
}
Interesting problem. Here a possible solution (although I'm not really happy with it myself..)
String str = "11020199,Abc Germany ,aduz,,444,bieb,dc,2 ,2222.00,whatever 5dc,222.22,22.00,\"\"98,00\"\",\"\"12,00\"\",21-09-2018,06:00";
// Replace the comma between double quotes with a replacement char you're sure isn't in the String:
// TODO: Use a more suitable character, I don't know what your text can/cannot contain
String modifiedStr = str.replaceAll("(\"\"[^,]+),([^,]+\"\")", "$1🍺$2");
// Now split by comma:
String[] array = modifiedStr.split(",");
// And then change the replacement char back again to a comma:
for(int i=0; i<array.length; i++)
array[i] = array[i].replace("🍺", ",");
Try it online.
NOTE: Assumes the values between double double-quotes will only contain a single comma.
If nothing else works you have to do it step by step. Check what comes next (comma or double quotes) and cut the next word.
public static String[] split(String s) {
List<String> l = new ArrayList<>();
int begin = 0;
while (begin < s.length()) {
int nextQuotes = s.indexOf("\"\"", begin);
if (nextQuotes == begin) {
l.add(s.substring(begin + 2, s.indexOf("\"\"", begin + 2)));
begin = s.indexOf("\"\"", begin + 2) + 2;
continue;
}
int nextComma = s.indexOf(',', begin);
if (nextComma == begin) {
l.add("");
begin++;
continue;
} else if (nextComma == -1) {
l.add(s.substring(begin));
begin = s.length();
continue;
}
l.add(s.substring(begin, nextComma));
begin = nextComma + 1;
}
return l.toArray(new String[] {});
}
Not the best solution but it works.
You can do it as below [You can improve extracting some part to some method, but this will work for you anyway]
String[] splittedData = s.split(",");
List<String> data = new ArrayList<>(splittedData.length);
StringBuilder sb = new StringBuilder();
for (String splittedDataPart : splittedData) {
splittedDataPart = splittedDataPart.trim();
if (sb.length() == 0 && !splittedDataPart.startsWith("\"")) {
data.add(splittedDataPart);
continue;
}
if (sb.length() != 0)
sb.append(",");
sb.append(splittedDataPart.replace("\"", ""));
if (splittedDataPart.endsWith("\"")) {
data.add(sb.toString());
sb.setLength(0);//clearing
}
}
I have string like "abc /123 /456" and I want to split it into two stings: "abc 123" and "abc 456".
I tried:
String[] str = MESSAGE.split("/")
But didn't provide required result. Could anyone, please, share any ideas with me how to perform it?
Just stick the pieces together in any way you need, like this:
String[] str = MESSAGE.split(" /");
String s1 = str[0] + " " + str[1];
String s2 = str[0] + " " + str[2];
Also notice that it'd be better to split the string using as pattern " /", that is, with a space before the slash.
you did just fine when deciding to split it , after that you should concat the first element of the splited array with all the other elements to achieve what you want.
here's some code to make it clearer.
public class main {
public static void main(String[] args) {
String MESSAGE = "abc /123 /456";
String[] str = MESSAGE.split("/") ;
String[] str2 = new String[str.length-1];
System.out.println(str[0]);
for ( int i=1 ; i<str.length ; i++) {
str2[i-1] = str[0]+str[i];
}
for ( int i=0 ; i<str2.length ; i++) {
System.out.println(str2[i]);
}
}
}
You will need to add a little logic after splitting the String.
This is how I would do it:
String s = "abc /123 /456";
String[] partsOfS = s.split("/");
String prefix = partsOfS[0];
for (int i = 1; i < partsOfS.length; i++) {
System.out.println(prefix + partsOfS[i]);
}
EDIT
For the case of the prefix not separated by / from the other parts of the String but only by space, you will probably need a second split and a second loop, like this:
String s = "abc 123/ 456/";
String[] splitBySpace = s.split(" ");
String prefix = splitBySpace[0];
String[] partsOfS = new String[splitBySpace.length - 1];
for (int i = 1; i < splitBySpace.length; i++) {
partsOfS[i - 1] = splitBySpace[i].replace("/", "");
}
for (int i = 0; i < partsOfS.length; i++) {
System.out.println(prefix + " " + partsOfS[i]);
}
There may be better solutions concerning performance and programming style, but this is working with your example String from the comment.
I'm trying to make an encryptor.What i want it to do:
Get the text i enter and reverse the first two letters of every word
and then display it again.
I have tried a lot of ways.This is the last one i've tried:
private void TranslateToEf(){
String storage = Display.getText();
String[] arr = storage.split("\\W+");
for ( String ss : arr) {
char c[] = ss.toCharArray();
char temp = c[0];
c[0] = c[1];
c[1] = temp;
String swappedString = new String(c);
Display.appendText(swappedString + " ");
}
}
You may want to consider maintaining all the delimiters lost from the first String.split("\\W+") so they can be included in the final result. I would do that with a String.split("\\w+")
You may also want to consider that when you swap the first two letters, if the first letter is capital it becomes lowercase and the second letter becomes uppercase. Otherwise, just do a direct swap.
Code sample:
public static void main(String[] args) throws Exception {
String data = "Hello;World! My name is John. I write code.";
String[] words = data.split("\\W+");
String[] delimiters = data.split("\\w+");
int delimiterIndex = 0;
StringBuilder sb = new StringBuilder();
for (String word : words) {
if (word.length() < 2) {
sb.append(word);
} else {
char firstLetter = word.charAt(0);
char secondLetter = word.charAt(1);
if (Character.isUpperCase(firstLetter)) {
// Swap the first two letters and change casing
sb.append(Character.toUpperCase(secondLetter))
.append(Character.toLowerCase(firstLetter));
} else {
// Swap the first two letters
sb.append(secondLetter)
.append(firstLetter);
}
// Append the rest of the word past the first two letters
sb.append(word.substring(2));
}
// Append delimiters
if (delimiterIndex < delimiters.length) {
// Skip blank delimiters if there are any
while (delimiters[delimiterIndex].isEmpty()) {
delimiterIndex++;
}
// Append delimiter
sb.append(delimiters[delimiterIndex++]);
}
}
data = sb.toString();
// Display result
System.out.println(data);
}
Results:
Ehllo;Owrld! Ym anme si Ojhn. I rwite ocde.
public class Encrypto {
public static void main(String[] args) {
String input="Hello World";
String [] word = input.split(" ");
// System.out.println(word[0]);
String encryWord="";
for(int i=0;i<word.length;i++){
if (word[i].length() > 0) {
String tmp0 = String.valueOf(word[i].charAt(1));
String tmp1 = String.valueOf(word[i].charAt(0));
encryWord += tmp0.toLowerCase() + tmp1.toLowerCase() + word[i].substring(2) + " ";
}else{
encryWord +=word[i];
}
}
System.out.println(encryWord);
}
}
I think answer is more helpful for you
There are a few problems.
Declare zz outside the loop if you want to use it outside.
Append zz on every iteration. Not just assign it.
Something like this,
private void TranslateToEf(){
String storage = Display.getText();
String[] arr = storage.split("\\W+");
String zz = "";
for ( String ss : arr) {
char c[] = ss.toCharArray();
char temp = c[0];
c[0] = c[1];
c[1] = temp;
String swappedString = new String(c);
String b= " ";
zz += swappedString + b;
}
Display.setText(zz + " ");
}
You are splitting with non-word (\W+) characters, but replacing it only with a space " ". This could alter the string with special characters.
Not sure what exactly you are looking for but i little modification in your code see if this suits your needs
String storage = "Test test t";
String[] arr = storage.split("\\W+");
String abc = "";
for ( String ss : arr) {
if(ss.length() > 1)
{
char c[] = ss.toCharArray();
char temp = c[0];
c[0] = c[1];
c[1] = temp;
String swappedString = new String( c );
String b = " ";
String zz = swappedString + b;
abc = abc + zz;
}else{
abc = abc + ss;
}
}
System.out.println(abc);
In Java strings are immutable. You can't modify them "on the fly", you need to reassign them to a new instance.
Additionally, you are setting the last display text to zz, but zz is a local variable to your loop, and therefore it gets re-instantiated with every iteration. In other words, you would be assigning to display only the last word!
Here is what you have to do to make it work:
String storage = Display.getText();
String[] arr = storage.split("\\W+");
String[] newText = new String[arr.length];
for ( int i = 0; i<arr.length; i++) {
String original = arr[i];
String modified = ((char) original.charAt(1)) + ((char) original.charAt(0)) + original.substring(2);
newText[i] = modified;
}
//Join with spaces
String modifiedText = Arrays.asList(newText).stream().collect(Collectors.join(" "));
Display.setText(modifiedText);
Note that:
1) We are assuming all strings have at least 2 chars
2) that your splitting logic is correct. Can you think some edge cases where your regexp fails?
I have a string that contains several keyword and is separated by space, and there are several string sets. I write a API to remove all the elements in those string sets from the space-separated string and return the remained space-separated string. And my API is restricted by string input/output type.
For example, input string S="A B C D E", there are two string sets S1={A,B}, S2={C}, my API has to remove A,B,C from S and return "D E".
Here is my code:
public String filterString( String keyword, Set<String> set1, String<String> set2 )
{
// convert string to set in order to remove set
Set<String> keywordSet = new HashSet<String>( Arrays.asList( keyword.split( "\\s+" ) ) );
keywordSet.removeAll( set1 );
keywordSet.removeAll( set2 );
// convert set to string
StringBuffer strBuf = new StringBuffer();
for ( String s : keywordSet )
strBuf.append( s + " " );
return strBuf.toString();
}
My problem: is there any better or optimal method to rewrite the implementation of my API??
You could use our friend, Regex, as shown here. You'd have to concatenate your sets into the expression in the Pattern.compile argument.
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class Module1{
public static void main(String[] asd){
String sourcestring = "source string to match with pattern";
Pattern re = Pattern.compile("[^ABC\\s+]");
Matcher m = re.matcher(sourcestring);
int mIdx = 0;
while (m.find()){
for( int groupIdx = 0; groupIdx < m.groupCount()+1; groupIdx++ ){
System.out.println( "[" + mIdx + "][" + groupIdx + "] = " + m.group(groupIdx));
}
mIdx++;
}
}
}
You could use char[] replace set1 and set2,then keywords toCharArray and foreach equals with before char[] replace ''. Last syso(not '').