OR condition in java substring method - java

While parsing the dynamic input string using the java substring method with start and end indexes, Can we use or condition in the end index of the substring method? Meaning end index could be either ')' or ',' for my use case.
Ex: my input string have below two formats
inputformat1 : Student(name: Joe, Batch ID: 23) is updated
inputformat2 : Student(name: John, ID:0, Batch ID: 2503, Result: pass) is updated
Now I am interested to get the "Batch ID" value every-time. I wanted to achieve this by substring method. Now I'm able to get the batch id value If I use any one of the indexes i.e, ')' or ','
String batchId= input.substring(input.indexOf("Batch ID: ")+9,input.indexOf(")"));
Can someone help me to the way to batch Id value basing on different end indexes?

You can use regex with replaceFirst to solve your problem for example ;
List<String> strings = Arrays.asList("Student(name: Joe, Batch ID: 23) is updated",
"Student(name: John, ID:0, Batch ID: 2503, Result: pass) is updated"
);
for (String string : strings) {
System.out.println(
string.replaceFirst(".*Batch ID:\\s+(\\d+).*", "$1")
);
}
Outputs
23
2503
If you want multiple groups you can also use Patterns like so :
Pattern pattern = Pattern.compile("name:\\s+(.*?),.*?Batch ID:\\s+(\\d+)");
Matcher matcher;
for (String string : strings) {
matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println(
String.format("name : %s, age : %s", matcher.group(1), matcher.group(2))
);
}
}
Outputs
name : Joe, age : 23
name : John, age : 2503

You could use Math.min():
String batchId = input.substring(input.indexOf("Batch ID: ") + 9,
Math.min(tail_old.indexOf(")"), tail_old.indexOf(",")));

Related

Using regex for doing string operation

I have a string
String s="my name is ${name}. My roll no is ${rollno} "
I want to do string operations to update the name and rollno using a method.
public void name(String name, String roll)
{
String new = s.replace(" ${name}", name).replace(" ${rollno}", roll);
}
Can we achieve the same using some other means like using regex to change after first "$" and similarly for the other?
You can use either Matcher#appendReplacement or Matcher#replaceAll (with Java 9+):
A more generic version:
String s="my name is ${name}. My roll no is ${rollno} ";
Matcher m = Pattern.compile("\\$\\{([^{}]+)\\}").matcher(s);
Map<String,String> replacements = new HashMap();
replacements.put("name","John");
replacements.put("rollno","123");
StringBuffer replacedLine = new StringBuffer();
while (m.find()) {
if (replacements.get(m.group(1)) != null)
m.appendReplacement(replacedLine, replacements.get(m.group(1)));
else
m.appendReplacement(replacedLine, m.group());
}
m.appendTail(replacedLine);
System.out.println(replacedLine.toString());
// => my name is John. My roll no is 123
Java 9+ solution:
Matcher m2 = Pattern.compile("\\$\\{([^{}]+)\\}").matcher(s);
String result = m2.replaceAll(x ->
replacements.get(x.group(1)) != null ? replacements.get(x.group(1)) : x.group());
System.out.println( result );
// => my name is John. My roll no is 123
See the Java demo.
The regex is \$\{([^{}]+)\}:
\$\{ - a ${ char sequence
([^{}]+) - Group 1 (m.group(1)): any one or more chars other than { and }
\} - a } char.
See the regex demo.

Split string based on parantheses

I'm writing Scala code which splits a line based on a colon (:).
Example, for an input which looked like:
sparker0i#outlook.com : password
I was doing line.split(" : ") (which is essentially Java) and printing the email and the password on Console.
Now my requirement has changed and now a line will look like:
(sparker0i#outlook.com,sparker0i) : password
I want to individually print the email, username and password separately.
I've tried Regex by first trying to split the parantheses, but that didn't work because it is not correct (val lt = line.split("[\\\\(||//)]")). Please guide me with the correct regex/split logic.
I'm not a scala user, but instead of split, I think you can use Pattern and matcher to extract this info, your regex can use groups like:
\((.*?),(.*?)\) : (.*)
regex demo
Then you can extract group 1 for email, group 2 for username and the 3rd group for password.
val input = "(sparker0i#outlook.com,sparker0i) : password"
val pattern = """\((.*?),(.*?)\) : (.*)""".r
pattern.findAllIn(string).matchData foreach {
m => println(m.group(1) + " " + m.group(2) + " " + m.group(3))
}
Credit for this post https://stackoverflow.com/a/3051206/5558072
The regex I would use:
\((.*?),([^)]+)\) : (.+)
Regex Demo
\( # Matches (
( # Start of capture group 1
(.*?) # Capture 0 or more characters until ...
) # End of capture group 1
, # matches ,
( # start of capture group 2
[^)]+ # captures one or more characters that are not a )
) # end of capture group 2
\) # Matches )
: # matches ' : '
( # start of capture group 3
(.+) # matches rest of string
) # end of capture group 3
The Java implementation would be:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Test
{
public static void main(String[] args) {
String s = "(sparker0i#outlook.com,sparker0i) : password";
Pattern pattern = Pattern.compile("\\((.*?),([^)]+)\\) : (.+)");
Matcher m = pattern.matcher(s);
if (m.matches()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
System.out.println(m.group(3));
}
}
}
Prints:
sparker0i#outlook.com
sparker0i
password
Java Demo
In scala 2.13, there is a simple solution without regrex:
Welcome to Scala 2.13.1 (OpenJDK 64-Bit Server VM, Java 1.8.0_222).
Type in expressions for evaluation. Or try :help.
scala> val input = "(sparker0i#outlook.com,sparker0i) : password"
input: String = (sparker0i#outlook.com,sparker0i) : password
scala> val s"($mail,$user) : $pwd" = input
mail: String = sparker0i#outlook.com
user: String = sparker0i
pwd: String = password
this is without doing much change
String s = "(sparker0i#outlook.com,sparker0i) : password";
// do whatever you were doing
String[] sArr = s.split(":");
sArr[0] = sArr[0].replaceAll("[(|)]",""); // just replace those parenthesis with empty string
System.out.println(sArr[0] + " " + sArr[1]);
Output
sparker0i#outlook.com,sparker0i password

Compare Multiple Differences in Java Strings

I have a string template that looks something like this:
This position is reserved for <XXXXXXXXXXXXXXXXXXXXXXXXXXX>. Start date is <XXXXXXXX>
Filled out, this might look like this (fixed width is preserved):
This position is reserved for <JOHN SMITH >. Start date is <20150228>
How can I extract multiple differences in a single String? I don't want to use an entire templating engine for one task if I can avoid it.
You can try regex like this :
public static void main(String[] args) {
String s = "This position is reserved for <JOHN SMITH >. Start date is <20150228>";
Pattern p = Pattern.compile(".*?<(.*?)>.*<(.*?)>");
Matcher m = p.matcher(s);
while(m.find()){
System.out.println("Name : " +m.group(1).trim());
System.out.println("Date : " +m.group(2).trim());
}
}
O/P :
Name : JOHN SMITH
Date : 20150228
If the template might be modified you could use a format pattern.
String expected = "This position is reserved for <JOHN SMITH >. Start date is <20150228>";
System.out.println(expected);
// define the output format
String template = "This position is reserved for <%-27s>. Start date is <%s>";
String name = "JOHN SMITH";
String startDate = "20150228";
// output the values using the defined format
System.out.println(String.format(template, name, startDate));

Intelligent String Parsing in java

I have an email Subject line that i need to parse. I need to find first occurance of any word given in a list of words and get the next word which can be separated by
('=' or ',' or ';' or 'blank' or '.').
for example
list of word for customer ["customer","client","kunden","kd.nr."]
list of word for Order ["order","auftrag","auftragsnummer","auftragnr."]
separator : [= , ; .]
subjectline: Customer 2013ABC has send an Aufrag 2056899A for Motif=A
I need to parse the information like
customer=2013ABC
order=2056899A
Motif=A
I am using Java 7 so Scanner class can be used as well.
Thanks for any tips in advance
You can achieve this by using regular expressions, here is a sample code:
Pattern p = Pattern.compile(".*(customer|client|kunden|kd\\.nr\\.)[=,;\\. ]*(\\w*).*(order|auftrag|auftragsnummer|auftragnr\\.)[=,;\\. ]*(\\w*).*[ ](.*)$", Pattern.CASE_INSENSITIVE);
String subject = "subjectline: kd.nr. 2013ABC has send an Auftrag 2056899A for Motif=A";
Matcher m = p.matcher(subject);
if(m.matches()) {
System.out.println(m.group(1) + " : " + m.group(2) );
System.out.println(m.group(3) + " : " + m.group(4));
System.out.println(m.group(5));
}
Hope this helps.

Java Pattern Matcher single or multiple with comma separated

I have a string, which I need to parse, I want to use pattern matcher
need help with pattern.
if string as below:
sometext : test1,test2
output should be:
test1
test2
if input string is :
sometext : test1
then output should be :
test1
as you can see, it can be multiple or single.
So, you just need to replace , with a space? I would suggest a simple
String output = sometext.replace(",", " ");
If you need a newline after the first word, you can do
String output = sometext.replace(",", System.getProperty("line.separator"));
instead.
If "sometext : " is included in the input, you can get rid of that first in the same way:
String output = input.replace("sometext : ", "").replace(",", " ");
First, you have to separate "test1,test2" from "sometext", then use replaceAll to get the tests array by the , token.
String foo = "sometext : test1,test2";
String[] fooArr = foo.split("[:]");
String tests = fooArr[1];
System.out.println(tests.replaceAll(",", " "));
​

Categories