Get a substring in a string with multiple occurring strings
I have a line like
(D@01)5(D@02)14100319530033M(D@03)1336009-A-A(D@04)141002A171(D@05)1(D@06)
Now I want to get the substring between (D@01)5(D@02)
If I have something like
(D@01)5(D@02)
I can get the details with
quantity = content.substring(content.indexOf("(D@01)") + 6, content.indexOf("(D@02)"));
But somethings D@02
may be different like @05
. Now how can I use a simple (D@
one to get the line in between. there are several repetitions(D@
This is basically what I want to do
content.substring(content.indexOf("(D@01)") + 6, content.nextOccurringIndexOf("(D@"));
source to share
I suppose you can do
int fromIndex = content.indexOf("(D@01)") + 6;
int toIndex = content.indexOf("(D@", fromIndex); // next occurring
if (fromIndex != -1 && toIndex != -1)
str = content.substring(fromIndex, toIndex);
Output
5
See http://ideone.com/RrUtBy for a demo.
source to share
Assuming the token and value are related in some way and you want to know each ( (D@01)
== 5
), you can use the API Pattern
/ Matcher
, for example
String text = "(D@01)5(D@02)14100319530033M(D@03)1336009-A-A(D@04)141002A171(D@05)1(D@06)";
Pattern p = Pattern.compile("\\(D@[0-9]+\\)");
Matcher m = p.matcher(text);
while (m.find()) {
String name = m.group();
if (m.end() < text.length()) {
String content = text.substring(m.end()) + 1;
content = content.substring(0, content.indexOf("("));
System.out.println(name + " = " + content);
}
}
What are the outputs
(D@01) = 5
(D@02) = 14100319530033M
(D@03) = 1336009-A-A
(D@04) = 141002A171
(D@05) = 1
Now, this is a bit cumbersome, I would create some sort of "marker" object that contains the key (D@01)
and its start and end indices. I would store this information in List
and truncate each value based on the end of the previous key and the start of the last key ... but that's just me;)
source to share
You can use regex capture groups if you want the content between (D@##)
Pattern p = Pattern.compile("(\\(D@\\d+\\))(.*?)(?=\\(D@\\d+\\))");
Matcher matcher = p.matcher("(D@01)5(D@02)14100319530033M(D@03)1336009-A-A(D@04)141002A171(D@05)1(D@06)");
while(matcher.find()) {
System.out.println(String.format("%s start: %2s end: %2s matched: %s ",
matcher.group(1), matcher.start(2), matcher.end(2), matcher.group(2)));
}
(D@01) start: 6 end: 7 matched: 5
(D@02) start: 13 end: 28 matched: 14100319530033M
(D@03) start: 34 end: 45 matched: 1336009-A-A
(D@04) start: 51 end: 61 matched: 141002A171
(D@05) start: 67 end: 68 matched: 1
source to share
Custom regex can be split on input - as suggested by @MadProgrammer. split()
the method creates a table String
s, so the order of occurrences of the sought values ββwill be exactly the same as the order of the values ββin the table created split()
. For example:
String input = "(D@01)5(D@02)14100319530033M(D@03)1336009-A-A(D@04)141002A171(D@05)1(D@06)";
String[] table = input.split("\(D@[0-9]+\)");
source to share
Try the following:
public static void main(String[] args) {
String input = "(D@01)5(D@02)14100319530033M(D@03)1336009-A-A(D@04)141002A171(D@05)1(D@06)";
Pattern p = Pattern.compile("\\(D@\\d+\\)(.*?)(?=\\(D@\\d+\\))");
Matcher matches = p.matcher(input);
while(matches.find()) {
int number = getNum(matches.group(0)); // parses the number
System.out.printf("%d. %s\n", number, matches.group(1)); // print the string
}
}
public static int getNum(String str) {
int start = str.indexOf('@') + 1;
int end = str.indexOf(')', start);
return Integer.parseInt(str.substring(start,end));
}
Result:
1. 5
2. 14100319530033M
3. 1336009-A-A
4. 141002A171
5. 1
source to share