I am trying to get an element from my string wich I have attained thtough a getSelectedValue().toString from a JList.
It returns [1] testString
What I am trying to do it only get the 1 from the string. Is there a way to only get that element from the string or remove all else from the string?
I have tried:
String longstring = Customer_list.getSelectedValue().toString();
int index = shortstring.indexOf(']');
String firstPart = myStr.substring(0, index);
You have many ways to do it, for example
Regex
String#replaceAll
String#substring
See below code to use all methods.
import java.util.*;
import java.lang.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Test {
public static void main(String args[]) {
String[] data = { "[1] test", " [2] [3] text ", " just some text " };
for (String s : data) {
String r0 = null;
Matcher matcher = Pattern.compile("\\[(.*?)\\]").matcher(s);
if (matcher.find()) {
r0 = matcher.group(1);
}
System.out.print(r0 + " ");
}
System.out.println();
for (String s : data) {
String r1 = null;
r1 = s.replaceAll(".*\\[|\\].*", "");
System.out.print(r1 + " ");
}
System.out.println();
for (String s : data) {
String r2 = null;
int i = s.indexOf("[");
int j = s.indexOf("]");
if (i != -1 && j != -1) {
r2 = s.substring(i + 1, j);
}
System.out.print(r2 + " ");
}
System.out.println();
}
}
However results may vary, for example String#replaceAll will give you wrong results when input is not what you expecting.
1 2 null
1 3 just some text
1 2 null
What worked best for me is the String#replace(charSequence, charSequence) combined with String#substring(int,int)
I have done as followed:
String longstring = Customer_list.getSelectedValue().toString();
String shortstring = longstring.substring(0, longstring.indexOf("]") + 1);
String shota = shortstring.replace("[", "");
String shortb = shota.replace("]", "");
My string has been shortened, and the [ and ] have been removed thereafter in 2 steps.
Related
This post is an update to this one : get specific character in a string with regex and remove unused zero
In the first place, i wanted to remove with an regular expression the unused zero in the last match.
I found that the regular expression is a bit overkill for what i need.
Here is what i would like now,
I would like to use split() method
to get from this :
String myString = "2020-LI50532-3329-00100"
this :
String data1 = "2020"
String data2 = "LI50532"
String data3 = "3329"
String data4 = "00100"
So then i can remove from the LAST data the unused Zero
to convert "00100" in "100"
And then concatenate all the data to get this
"2020-LI50532-3329-100"
Im not familiar with the split method, if anyone can enlight me about this ^^
You can use substring method to get rid of the leading zeros...
String myString = "2020-LI50532-3329-00100";
String[] data = myString.split("-");
data[3] = data[3].substring(2);
StringBuilder sb = new StringBuilder();
sb.append(data[0] + "-" + data[1] + "-" + data[2] + "-" + data[3]);
String result = sb.toString();
System.out.println(result);
Assuming that we want to remove the leading zeroes of ONLY the last block, maybe we can:
Extract the last block
Convert it to Integer and back to String to remove leading zeroes
Replace the last block with the String obtained in above step
Something like this:
public String removeLeadingZeroesFromLastBlock(String text) {
int indexOfLastDelimiter = text.lastIndexOf('-');
if (indexOfLastDelimiter >= 0) {
String lastBlock = text.substring(indexOfLastDelimiter + 1);
String lastBlockWithoutLeadingZeroes = String.valueOf(Integer.valueOf(lastBlock)); // will throw exception if last block is not an int
return text.substring(0, indexOfLastDelimiter + 1).concat(lastBlockWithoutLeadingZeroes);
}
return text;
}
Solution using regex:
public class Main {
public static void main(String[] args) {
// Test
System.out.println(parse("2020-LI50532-3329-00100"));
System.out.println(parse("2020-LI50532-3329-00001"));
System.out.println(parse("2020-LI50532-03329-00100"));
System.out.println(parse("2020-LI50532-03329-00001"));
}
static String parse(String str) {
return str.replaceAll("0+(?=[1-9]\\d*$)", "");
}
}
Output:
2020-LI50532-3329-100
2020-LI50532-3329-1
2020-LI50532-03329-100
2020-LI50532-03329-1
Explanation of the regex:
One or more zeros followed by a non-zero digit which can be optionally followed by any digit(s) until the end of the string (specified by $).
Solution without using regex:
You can do it also by using Integer.parseInt which can parse a string like 00100 into 100.
public class Main {
public static void main(String[] args) {
// Test
System.out.println(parse("2020-LI50532-3329-00100"));
System.out.println(parse("2020-LI50532-3329-00001"));
System.out.println(parse("2020-LI50532-03329-00100"));
System.out.println(parse("2020-LI50532-03329-00001"));
}
static String parse(String str) {
String[] parts = str.split("-");
try {
parts[parts.length - 1] = String.valueOf(Integer.parseInt(parts[parts.length - 1]));
} catch (NumberFormatException e) {
// Do nothing
}
return String.join("-", parts);
}
}
Output:
2020-LI50532-3329-100
2020-LI50532-3329-1
2020-LI50532-03329-100
2020-LI50532-03329-1
you can convert the last string portion to integer type like below for removing unused zeros:
String myString = "2020-LI50532-3329-00100";
String[] data = myString.split("-");
data[3] = data[3].substring(2);
StringBuilder sb = new StringBuilder();
sb.append(data[0] + "-" + data[1] + "-" + data[2] + "-" + Integer.parseInt(data[3]));
String result = sb.toString();
System.out.println(result);
You should avoid String manipulation where possible and rely on existing types in the Java language. One such type is the Integer. It looks like your code consists of 4 parts - Year (Integer) - String - Integer - Integer.
So to properly validate it I would use the following code:
Scanner scan = new Scanner("2020-LI50532-3329-00100");
scan.useDelimiter("-");
Integer firstPart = scan.nextInt();
String secondPart = scan.next();
Integer thirdPart = scan.nextInt();
Integer fourthPart = scan.nextInt();
Or alternatively something like:
String str = "00100";
int num = Integer.parseInt(str);
System.out.println(num);
If you want to reconstruct your original value, you should probably use a NumberFormat to add the missing 0s.
The main points are:
Always try to reuse existing code and tools available in your language
Always try to use available types (LocalDate, Integer, Long)
Create your own types (classes) and use the expressiveness of the Object Oriented language
public class Test {
public static void main(String[] args) {
System.out.println(trimLeadingZeroesFromLastPart("2020-LI50532-03329-00100"));
}
private static String trimLeadingZeroesFromLastPart(String input) {
String delem = "-";
String result = "";
if (input != null && !input.isEmpty()) {
String[] data = input.split(delem);
StringBuilder tempStrBldr = new StringBuilder();
for (int idx = 0; idx < data.length; idx++) {
if (idx == data.length - 1) {
tempStrBldr.append(trimLeadingZeroes(data[idx]));
} else {
tempStrBldr.append(data[idx]);
}
tempStrBldr.append(delem);
}
result = tempStrBldr.substring(0, tempStrBldr.length() - 1);
}
return result;
}
private static String trimLeadingZeroes(String input) {
int idx;
for (idx = 0; idx < input.length() - 1; idx++) {
if (input.charAt(idx) != '0') {
break;
}
}
return input.substring(idx);
}
}
Output:
2020-LI50532-3329-100
I have written following code to get next word from a string in Java. I feel its very raw and I shouldn't have to write so much code for this but couldn't find any other way. Want to know if there are better ways available to do same:
public static String getNextWord(String str, String word) {
String nextWord = null;
// to remove multi spaces with single space
str = str.trim().replaceAll(" +", " ");
int totalLength = str.length();
int wordStartIndex = str.indexOf(word);
if (wordStartIndex != -1) {
int startPos = wordStartIndex + word.length() + 1;
if (startPos < totalLength) {
int nextSpaceIndex = str.substring(startPos).indexOf(" ");
int endPos = 0;
if (nextSpaceIndex == -1) {
// we've reached end of string, no more space left
endPos = totalLength;
} else {
endPos = startPos + nextSpaceIndex;
}
nextWord = str.substring(startPos, endPos);
}
}
return nextWord;
}
Note: the input word could be anything (multi words, single word, a word not in string etc).
Test:
String text = "I am very happy with life";
System.out.println(StringUtil.getNextWord(text, "I"));
System.out.println(StringUtil.getNextWord(text, "I am"));
System.out.println(StringUtil.getNextWord(text, "life"));
System.out.println(StringUtil.getNextWord(text, "with"));
System.out.println(StringUtil.getNextWord(text, "fdasfasf"));
System.out.println(StringUtil.getNextWord(text, text));
Output:
am
very
null
life
null
null
This sounds like a job for regex. Something like this:
public static String getNextWord(String str, String word){
Pattern p = Pattern.compile(word+"\\W+(\\w+)");
Matcher m = p.matcher(str);
return m.find()? m.group(1):null;
}
Hope this will serve your purpose.
public static String getNextWord(String str, String word) {
String[] words = str.split(" "), data = word.split(" ");
int index = Arrays.asList(words).indexOf((data.length > 1) ? data[data.length - 1] : data[0]);
return (index == -1) ? "Not Found" : ((index + 1) == words.length) ? "End" : words[index + 1];
}
Input (single word) :
String str = "Auto generated method stub";
String word = "method";
Out Put:
next word: stub
Input (multi-words) :
String str = "Auto generated method stub";
String word = "Auto generated";
Out Put:
next word: method
Input (missing word) :
String str = "Auto generated method stub";
String word = "was";
Out Put:
next word: Not Found
Input (end word) :
String str = "Auto generated method stub";
String word = "stub";
Out Put:
next word: End
You can create an array of words by doing this:
String[] words = str.split(" ");
This splits the string into strings when separated by a space. Note you keep needing to trim the str as you want to.
Now, you can somehow search in the array by finding some word and adding 1 to the index to get the next one.
nextword = words[words.indexOf(word) + 1];
I think, this solution works correctly:
public static String getNextWord(String str, String word) {
String[] strArr = str.split(word);
if(strArr.length > 1) {
strArr = strArr[1].trim().split(" ");
return strArr[0];
}
return null;
}
You can try the below code.
public static String getNextWord(String str, String word) {
try {
List<String> text = Arrays.asList(str.split(" "));
List<String> list = Arrays.asList(word.split(" "));
int index_of = text.indexOf(list.get(list.size() - 1));
return (index_of == -1) ? null : text.get(index_of + 1);
} catch(Exception e) {
return null;
}
}
Hope this is what you are looking for:
public static void main(String[] args) {
String text = "I am very happy with life";
System.out.println(getNextWord(text,"am"));
System.out.println(getNextWord(text,"with"));
System.out.println(getNextWord(text,"happy"));
System.out.println(getNextWord(text,"I"));
System.out.println(getNextWord(text,"life"));
}
public static String getNextWord(String text,String finditsNext){
String result = "There is no next string";
try {
int findIndex = text.indexOf(finditsNext);
String tep = text.substring(findIndex);
if(tep.indexOf(" ") >0) {
tep = tep.substring(tep.indexOf(" ") + 1);
if(tep.indexOf(" ") >0)
result = tep.substring(0, tep.indexOf(" "));
else
result = tep;
}
}catch (IndexOutOfBoundsException ex){
}
return result;
}
The output for the above is:
very
life
with
am
There is no next string
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()]);
}
}
Im trying to split some characters in Java that contains "," , ":" and "-"
For instance ,
if the input is 58,1:2-4, it should produce the following output
Booknumber: 58
Chapter Number: 1
Verses = [2,3,4] (since 2-4 is the
values from 2 to 4)
Following is the code that I have tried,
private int getBookNumber() {
bookNumber = chapterNumber.split("[,]")[0];
return Integer.valueOf(bookNumber);
}
private int getChapterNumber() {
chapterNumber = sample.split("[:]")[0];
verseNumbers = sample.split("[:]")[1];
return Integer.valueOf(chapterNumber);
}
private List<Integer> getVerseNumbers(String bookValue) {
List<Integer> verseNumList = new ArrayList<>();
if (bookValue.contains("-")) {
//TODO parse - separated string
} else {
verseNumList.add(Integer.valueOf(bookValue));
}
return verseNumList;
}
I would invoke them in the following manner sequentially
int chapterNumber = getChapterNumber();
int bookNumber = getBookNumber();
List<Integer> verseNumbers = getVerseNumbers(this.verseNumbers);
But Im getting Caused by: java.lang.NumberFormatException: Invalid int: "58 , 1 " in the line int chapterNumber = getChapterNumber();
is there an efficient way to parse this string ?
You should change getChapterNumber like this:
private int getChapterNumber() {
chapterNumber = sample.split("[:]")[0];
verseNumbers = sample.split("[:]")[1];
return Integer.valueOf(chapterNumber.split("[,]")[1]);
}
But the best would be to use matcher:
String line = "58,1:2-4";
Pattern pattern = Pattern.compile("(\\d+),(\\d+):(.*)");
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
System.out.println("group 1: " + matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
System.out.println("group 3: " + matcher.group(3));
}
Output:
group 1: 58
group 2: 1
group 3: 2-4
I might approach this using base string methods to avoid the heavy equipment which comes with a regex matcher:
String input = "58,1:2-4";
int commaIndex = input.indexOf(",");
int colonIndex = input.indexOf(":");
int bookNumber = Integer.valueOf(input.substring(0, commaIndex));
int chapterNumber = Integer.valueOf(input.substring(commaIndex+1, colonIndex));
String verseString = input.substring(colonIndex+1);
String[] verses = verseString.split("-");
int startVerse = Integer.valueOf(verses[0]);
int endVerse = Integer.valueOf(verses[1]);
int[] allVerses = new int[endVerse - startVerse + 1];
for (int i=0; i < allVerses.length; ++i) {
allVerses[i] = startVerse + i;
}
I have text file which looks like this :
ABC=-1 Temp=2 Try=34 Message="some text" SYS=3
ABC=-1 Temp=5 Try=40 Message="some more and different text" SYS=6
and the pattern continues but only the numeric values and text inside the " " is changed.
NOTE: the Message= could have multiple quotes as well.
I want to store the value of ABC,Temp,Try and SYS to int variables
And Message to a String variable.
I am currently using:
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
int count = line.indexOf("ABC=");
if (count >= 0) {
int clear = line.charAt(count + 3);
}
}
scanner.close();
I thought of using the Scanner class and read line by line, but I am confused about how can I classify the line in different variables?
First make a class that represents the data:
public static class MyData { // please pick a better name
final int abc;
final int temp;
final int tryNumber; // try is a keyword
final String message;
final int sys;
public MyData(int abc, int temp, int tryNumber, String message, int sys) {
this.abc = abc;
this.temp = temp;
this.tryNumber = tryNumber;
this.message = message;
this.sys = sys;
}
}
Then make a method that transforms a String into this class using Regex capture groups:
private static Pattern p =
Pattern.compile("ABC=([^ ]+) Temp=([^ ]+) Try=([^ ]+) Message=\"(.+)\" SYS=([^ ]+)");
private static MyData makeData(String input) {
int abc = 0, temp = 0, tryNumber = 0, sys = 0;
String message = "";
Matcher m = p.matcher(input);
if (!(m.find()) return null;
abc = Integer.parseInt(m.group(1));
temp = Integer.parseInt(m.group(2));
tryNumber = Integer.parseInt(m.group(3));
message = m.group(4);
sys = Integer.parseInt(m.group(5));
return new MyData(abc, temp, tryNumber, message, sys);
}
Then read the file using a scanner:
public static void main (String... args) throws Exception {
File file = new File("/path/to/your/file.txt");
List<MyData> dataList = new ArrayList<>();
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
MyData data = makeData(line);
if(data != null) dataList.add(data);
}
scanner.close();
}
Here's a completely working demo on ideone
You can use regex for this kind of parsing with a pattern of:
"ABC=([+-]?\\d+) Temp=([+-]?\\d+) Try=([+-]?\\d+) Message=\"(.+)\" SYS=([+-]?\\d+)"
Pattern Breakdown (Pattern Reference):
ABC= - literal string
([+-]?\\d+) - captures a positive or negative number in capture group 1
Temp= - literal string
([+-]?\\d+) - captures a positive or negative number in capture group 2
Try= - literal string
([+-]?\\d+) - captures a positive or negative number in capture group 3
Message= - literal string
\"(.+)\" captures a string in between double quotes in capture group 4
SYS= - literal string
([+-]?\\d+) - captures a positive or negative number in capture group 5
If the String matches the pattern you can extract your values like this:
public static void main(String[] args) throws Exception {
List<String> data = new ArrayList() {{
add("ABC=-1 Temp=2 Try=34 Message=\"some text\" SYS=3");
add("ABC=-1 Temp=5 Try=40 Message=\"some more \"and\" different text\" SYS=6");
}};
String pattern = "ABC=([+-]?\\d+) Temp=([+-]?\\d+) Try=([+-]?\\d+) Message=\"(.+)\" SYS=([+-]?\\d+)";
int abc = 0;
int temp = 0;
int tryNum = 0;
String message = "";
int sys = 0;
for (String d : data) {
Matcher matcher = Pattern.compile(pattern).matcher(d);
if (matcher.matches()) {
abc = Integer.parseInt(matcher.group(1));
temp = Integer.parseInt(matcher.group(2));
tryNum = Integer.parseInt(matcher.group(3));
message = matcher.group(4);
sys = Integer.parseInt(matcher.group(5));
System.out.printf("%d %d %d %s %d%n", abc, temp, tryNum, message, sys);
}
}
}
Results:
-1 2 34 some text 3
-1 5 40 some more "and" different text 6
If you are already using the indexOf approach, the following code will work
String a = "ABC=-1 Temp=2 Try=34 Message=\"some text\" SYS=3";
int abc_index = a.indexOf("ABC");
int temp_index = a.indexOf("Temp");
int try_index = a.indexOf("Try");
int message_index = a.indexOf("Message");
int sys_index = a.indexOf("SYS");
int length = a.length();
int abc = Integer.parseInt(a.substring(abc_index + 4, temp_index - 1));
int temp = Integer.parseInt(a.substring(temp_index + 5, try_index - 1));
int try_ = Integer.parseInt(a.substring(try_index + 4, message_index - 1));
String message = a.substring(message_index + 9, sys_index - 2);
int sys = Integer.parseInt(a.substring(sys_index + 4, length));
System.out.println("abc : " + abc);
System.out.println("temp : " + temp);
System.out.println("try : " + try_);
System.out.println("message : " + message);
System.out.println("sys : " + sys);
This will give you the following
abc : -1
temp : 2
try : 34
message : some text
sys : 3
This will work only if the string data you get has this exact syntax, ie, it contains ABC, Temp, Try, Message, and SYS. Hope this helps.