String output with quotes - java

I get in put string as below
{key: IsReprint, value:COPY};{key: IsCancelled, value:CANCELLED}
I want to convert above string as below in my output...,want to add quotes to the string (key , value pairs).
{"key": "IsReprint", "value":"COPY"};{"key": "IsCancelled", "value":"CANCELLED"}
Please assist..thanks in advance..
String input="{key: IsReprint, value:COPY};{key: IsCancelled,value:CANCELLED}";
if(input.contains("key:") && input.contains("value:") ){
input=input.replaceAll("key", "\"key\"");
input=input.replaceAll("value", "\"value\"");
input=input.replaceAll(":", ":\"");
input=input.replaceAll("}", "\"}");
input=input.replaceAll(",", "\",");
//System.out.println("OUTPUT----> "+input);
}
I above code has problem if input string as below
{key: BDTV, value:Africa Ltd | Reg No: 433323240833-C23441,GffBLAB | VAT No: 4746660239035Level 6}

You could use regex to accomplish the same, but more concisely:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JsonScanner {
private final static String JSON_REGEX = "\\{key: (.*?), value:(.*?)(\\};|\\}$)";
/**
* Splits the JSON string into key/value tokens.
*
* #param json the JSON string to format
* #return the formatted JSON string
*/
private String findMatched(String json) {
Pattern p = Pattern.compile(JSON_REGEX);
Matcher m = p.matcher(json);
StringBuilder result = new StringBuilder();
while (m.find()) {
result.append("\"key\"=\"" + m.group(1) + "\", ");
result.append("\"value\"=\"" + m.group(2) + "\" ; ");
System.out.println("m.group(1)=" + m.group(1) + " ");
System.out.println("m.group(2)=" + m.group(2) + " ");
System.out.println("m.group(3)=" + m.group(3) + "\n");
}
return result.toString();
}
public static void main(String... args) {
JsonScanner jsonScanner = new JsonScanner();
String result = jsonScanner.findMatched("{key: TVREG, value:WestAfrica Ltd | VAT No: 1009034324829/{834324}<br/>Plot No.56634773,Road};{key: REGISTRATION, value:SouthAfricaLtd | VAT No: 1009034324829/{834324}<br />Plot No. 56634773, Road}");
System.out.println(result);
}
}
You might have to tweak the regex or output string to meet your exact requirements, but this should give you an idea of how to get started...

You have to escape characters
How do I escape a string in Java?
For example:
String s = "{\"key\": \"IsReprint\""; // will be print as {"key": "IsReprint"

The double quote character has to be escaped with a backslash in a Java string literal. Other characters that need special treatment include:
Carriage return and newline: "\r" and "\n"
Backslash: "\"
Single quote: "\'"
Horizontal tab and form feed: "\t" and "\f".

Here is a solution using a regexp to split your input into key / value pairs and then aggregating the result using the format you wish :
// Split key value pairs
final String regexp = "\\{(.*?)\\}";
final Pattern p = Pattern.compile(regexp);
final Matcher m = p.matcher(input);
final List<String[]> keyValuePairs = new ArrayList<>();
while (m.find())
{
final String[] keyValue = input.substring(m.start() + 1, m.end() - 1) // "key: IsReprint, value:COPY"
.substring(5) // "IsReprint, value:COPY"
.split(", value:"); // ["IsReprint", "COPY"]
keyValuePairs.add(keyValue);
}
// Aggregate
final List<String> newKeyValuePairs = keyValuePairs.stream().map(keyValue ->
{
return "{\"key\": \"" + keyValue[0] + "\", \"value\":\"" + keyValue[1] + "\"}";
}).collect(Collectors.toList());
System.out.println(StringUtils.join(newKeyValuePairs.toArray(), ";"));
The result for the folowing input string
final String input = "{key: IsReprint, value:COPY};{key: IsCancelled, value:CANCELLED};{key: BDTV, value:Africa Ltd | Reg No: 433323240833-C23441,GffBLAB | VAT No: 4746660239035<br />Level 6}";
is {"key": "IsReprint", "value":"COPY"};{"key": "IsCancelled", "value":"CANCELLED"};{"key": "BDTV", "value":"Africa Ltd | Reg No: 433323240833-C23441,GffBLAB | VAT No: 4746660239035<br />Level 6"}

This gives the exact result as you want!
public static void main(String s[]){
String test = "{key: TVREG, value:WestAfrica Ltd | VAT No: 1009034324829/{834324}<br />Plot No. 56634773, Road};{key: REGISTRATION, value:SouthAfricaLtd | VAT No: 1009034324829/{834324}<br />Plot No. 56634773, Road}";
StringBuilder sb= new StringBuilder();
String[] keyValOld = test.split(";");
for(int j=0; j<keyValOld.length; j++){
String keyVal = keyValOld[j].substring(1,keyValOld[j].length()-1);
String[] parts = keyVal.split("(:)|(,)",4);
sb.append("{");
for (int i = 0; i < parts.length; i += 2) {
sb.append("\""+parts[i].trim()+"\": \""+parts[i + 1].trim()+"\"");
if(i+2<parts.length) sb.append(", ");
}
sb.append("};");
}
System.out.println(sb.toString());
}

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NewClass {
public static void main(String[] args) {
String input="{key: IsReprint, value:COPY};{key: IsCancelled, value:CANCELLED};{key: BDTV,value:Africa Ltd | Reg No: 433323240833-C23441,GffBLAB | VAT No: 4746660239035 Level 6}";
Matcher m1 = Pattern.compile("key:" + "(.*?)" + ",\\s*value:").matcher(input);
Matcher m2 = Pattern.compile("value:" + "(.*?)" + "}").matcher(input);
StringBuilder sb = new StringBuilder();
while(m1.find() && m2.find()){
sb.append("{\"key\": ")
.append("\"")
.append(m1.group(1).trim())
.append("\", \"value\":")
.append("\"")
.append(m2.group(1).trim())
.append("\"};");
}
String output = sb.deleteCharAt(sb.length()-1).toString();
System.out.println(output);
}
}

Related

How can I add space between bracket and single quotation mark in java?

I am trying to convert the following string
Insert into table01 values('abcd01','abcd02','abcd03')
to
Insert into table01 values( 'abcd01', 'abcd02', 'abcd03' )
My code:
package layout;
public class String02 {
public String Replace01(String testString) {
String string01 = "";
string01 = testString.replaceAll("\\('", "\\( ");
string01 = testString.replaceAll("\\)", " \\)");
string01 = testString.replaceAll(",", ", ");
return string01;
}
public static void main(String[] args) {
String02 app = new String02();
String testString = "Insert into table01 values('abcd01','abcd02','abcd03')";
String s1 = app.Replace01(testString);
System.out.println(s1);
}
}
string01 = testString.replaceAll("\\('", "\\( ");
string01 = testString.replaceAll("\\)", " \\)");
string01 = testString.replaceAll(",", ", ");
Strings are immutable. You can't keep operating on the original string as a new string is returned from each replaceAll() statement.
The code should be:
string01 = testString.replaceAll("\\('", "\\( '");
string01 = string01.replaceAll("\\)", " \\)");
string01 = string01.replaceAll(",", ", ");
Also, your first replaceAll(...) statement was incorrect, since you missed the ' in the replacement string.
The error was mainly that you did not use string01 for the second and third replacement,
but the original testString. (replace(All/First) will not change the string itself, but yield a new string).
So the first and second replacements are lost.
Then you do not need regular expression replaces. You can write all like:
string01 = testString.replace("('", "( '")
.replace(")", " )")
.replace("','", "', '");
You can use the regex ('(?=\\))|\\,|\\() and capture group reference $1 with replaceAll() method :
String testString = "Insert into table01 values('abcd01','abcd02','abcd03')";
String string01 = testString.replaceAll("('(?=\\))|\\,|\\()", "$1 ");
System.out.println(string01);
(...) : capture group
$1 : capture group reference
| : OR operator
(?=...) : positive lookahead to capture ' before )
Output:
Insert into table01 values( 'abcd01', 'abcd02', 'abcd03' )
If you are having trouble with regular expressions, do consider going back to the basics.
public class String02 {
public String Replace01(String testString) {
String string01 = "";
char ch;
for(int i=0; i<testString.length(); i++){
ch = testString.charAt(i);
if(ch=='(' || ch==','){
if((i+1)<testString.length() && testString.charAt(i+1)!=' '){
string01 += ch + " ";
continue;
}
}else if (ch==')'){
if((i-1)>=0 && testString.charAt(i-1)!=' '){
string01 += " " + ch;
continue;
}
}
string01 += ch;
}
return string01;
}
public static void main(String[] args) {
String02 app = new String02();
String testString = "Insert into table01 values('abcd01','abcd02','abcd03')";
String s1 = app.Replace01(testString);
System.out.println(s1);
}
}
You might also use lookarounds to find the specific positions, and in the replacement use a single space.
(?<=\(|',)(?=')|(?<=')(?=\))
See the positions in this regex demo or a Java demo.
(?<=\(|',)(?=') Positive lookbehind assertion, if at the left is either ( or ', and at the right is '
| Or
(?<=')(?=\)) Positive lookbehind assertions, if at the left is ' and at the right is )
Example
String s = "Insert into table01 values('abcd01','abcd02','abcd03')";
String result = s.replaceAll("(?<=\\(|',)(?=')|(?<=')(?=\\))", " ");
System.out.println(result);
Output
Insert into table01 values( 'abcd01', 'abcd02', 'abcd03' )

Split string and extract text and number

I have to divide an address into street and number. Examples
Lievensberg 31D
Jablunkovska 21/2
Weimarstraat 113 A
Pastoor Baltesenstraat 22
Van Musschenboek strasse 84
I need to split like this:
Street1: Lievensberg
Number1: 31D
Street2: Jablunkovska
Number2: 21/2
Street3: Weimarstraat
Number3: 113 A
Street4: Pastoor Baltesenstraat
Number4: 22
Street5: Van Musschenboek strasse
Number5: 84
I used this code but not working, because I need to split only when the character after the white space will be a number:
String[] arrSplit = address_line.split("\\s");
for (int i = 0; i < arrSplit.length; i++) {
System.out.println(arrSplit[i]);
}
But I don't know how to do it so that all my requirements are met. Any idea?
If the number can be optional, instead of using split, you could use 2 capturing groups where the second group is optional.
^([^\d\r\n]+?)(?:\h*(\d.*)|$)
Explanation
^ Start of string
([^\d\r\n]+?) Match 1+ times any char except a digit or newline non greedy
(?: Non capture group
\h*(\d.*) Match 0+ horizontal whitespace chars
| Or
$ End of string
) Close non capture group
Regex demo | Java demo
Example code
String regex = "^([^\\d\\r\\n]+?)(?:\\h*(\\d.*)|$)";
String string = "Lievensberg 31D\n"
+ "Jablunkovska 21/2\n"
+ "Weimarstraat 113 A\n"
+ "Pastoor Baltesenstraat 22\n"
+ "Van Musschenboek strasse 84\n"
+ "Lievensberg";
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Street: " + matcher.group(1));
if (matcher.group(2) != null) {
System.out.println("Number: " + matcher.group(2));
}
System.out.println("------------------");
}
Output
Street: Lievensberg
Number: 31D
------------------
Street: Jablunkovska
Number: 21/2
------------------
Street: Weimarstraat
Number: 113 A
------------------
Street: Pastoor Baltesenstraat
Number: 22
------------------
Street: Van Musschenboek strasse
Number: 84
------------------
Street: Lievensberg
------------------
Something like this:
ArrayList<String> list = new ArrayList();
list.add("Lievensberg 31D");
list.add("Jablunkovska 21/2");
list.add("Weimarstraat 113 A");
list.add("Pastoor Baltesenstraat 22");
list.add("Van Musschenboek strasse 84");
for(int i=0;i<list.size();i++){
System.out.println("Street"+(i+1)+": "+ list.get(i).split("\\s+(?=\\d)")[0]);
System.out.println("Number"+(i+1)+": "+ list.get(i).split("\\s+(?=\\d)")[1]);
}
You can use regex to verify first whether it matches or not, then only process it.
String str1 = "Lievensberg 31D"; // street = Lievensberg, number = 31D
String str2 = "Lievensberg NN31D"; // doesn't matches
String str3 = "Lievensberg"; // street = Lievensberg, number = null
String str4 = "Pastoor Baltesenstraat 22"; // street = Pastoor Baltesenstraat, number = 22
Pattern pattern = Pattern.compile("([a-zA-Z ]+?)(\\s(\\d+)(.*))?");
Matcher matcher = pattern.matcher(str1);
if(matcher.matches()) {
String street = matcher.group(1);
String number = matcher.group(2) != null ? matcher.group(3) + matcher.group(4) : null;
System.out.println("street = " + street);
System.out.println("number = " + number);
}
You can use this logic:
Find the index of the first number
Split the string based on this index
For better understanding use below code
public static void main(String[] args) {
String address_line = "Weimarstraat 113 A";
// Find index of first number
Matcher matcher = Pattern.compile("\\d+").matcher(address_line);
int i = -1;
for(char c: address_line.toCharArray() ){
if('0'<=c && c<='9')
break;
i++;
}
//Split string using index
System.out.println(address_line.substring(0, i));
System.out.println(address_line.substring(i+1));
}
Its output will be:
Weimarstraat
113 A
Here's a simple solution using regex and split:
String str = "Jablunkovska 21/2";
String[] split = str.split("\\s(?=\\d)", 2);
System.out.println(Arrays.toString(split));
Output:
[Jablunkovska, 21/2]
The expression (?=\\d) is a lookahead for a digit, so it doesn't get removed with the split.

Java parse string using regex into variables

I need to extract variables from a string.
String format = "x:y";
String string = "Marty:McFly";
Then
String x = "Marty";
String y = "McFly";
but the format can be anything it could look like this y?x => McFly?Marty
How to solve this using regex?
Edit: current solution
String delimiter = format.replace(Y, "");
delimiter = delimiter.replaceAll(X, "");
delimiter = "\\"+delimiter;
String strings[] = string.split(delimiter);
String x;
String y;
if(format.startsWith(X)){
x = strings[0];
y = strings[1];
}else{
y = strings[0];
x = strings[1];
}
System.out.println(x);
System.out.println(y);
This works well, but I would prefer more clean solution.
There is no need for regex at all.
public static void main(String[] args) {
test("x:y", "Marty:McFly");
test("y?x", "McFly?Marty");
}
public static void test(String format, String input) {
if (format.length() != 3 || Character.isLetterOrDigit(format.charAt(1))
|| (format.charAt(0) != 'x' || format.charAt(2) != 'y') &&
(format.charAt(0) != 'y' || format.charAt(2) != 'x'))
throw new IllegalArgumentException("Invalid format: \"" + format + "\"");
int idx = input.indexOf(format.charAt(1));
if (idx == -1 || input.indexOf(format.charAt(1), idx + 1) != -1)
throw new IllegalArgumentException("Invalid input: \"" + input + "\"");
String x, y;
if (format.charAt(0) == 'x') {
x = input.substring(0, idx);
y = input.substring(idx + 1);
} else {
y = input.substring(0, idx);
x = input.substring(idx + 1);
}
System.out.println("x = " + x);
System.out.println("y = " + y);
}
Output
x = Marty
y = McFly
x = Marty
y = McFly
If the format string can be changed to be a regex, then using named-capturing groups will make it very simple:
public static void main(String[] args) {
test("(?<x>.*?):(?<y>.*)", "Marty:McFly");
test("(?<y>.*?)\\?(?<x>.*)", "McFly?Marty");
}
public static void test(String regex, String input) {
Matcher m = Pattern.compile(regex).matcher(input);
if (! m.matches())
throw new IllegalArgumentException("Invalid input: \"" + input + "\"");
String x = m.group("x");
String y = m.group("y");
System.out.println("x = " + x);
System.out.println("y = " + y);
}
Same output as above, including value order.
You can use the following regex (\\w)(\\W)(\\w)
This will find any alphanumeric characters followed by any non alpha-numeric followed by another set of alpha numeric characters. The parenthesis will group the finds so group 1 will be parameter 1, group 2 will be the delimiter and group 3 will be parameter 2.
Comparing parameter 1 with parameter 2 can determine which lexical order they go in.
Sample
public static void main(String[] args) {
testString("x:y", "Marty:McFly");
testString("x?y", "Marty?McFly");
testString("y:x", "Marty:McFly");
testString("y?x", "Marty?McFly");
}
/**
*
*/
private static void testString(String format, String string) {
String regex = "(\\w)(\\W)(\\w)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(format);
if (!matcher.find()) throw new IllegalArgumentException("no match found");
String delimiter = matcher.group(2);
String param1 = matcher.group(1);
String param2 = matcher.group(3);
String[] split = string.split("\\" + delimiter);
String x;
String y;
switch(param1.compareTo(param2)) {
case 1:
x = split[1];
y = split[0];
break;
case -1:
case 0:
default:
x = split[0];
y = split[1];
};
System.out.println("String x: " + x);
System.out.println("String y: " + y);
System.out.println(String.format("%s%s%s", x, delimiter, y));
System.out.println();
}
This approach will allow you to have any type of format not just x and y. You can have any format that matches the regular expression.

Initials from two names plus full surname

I'm struggling with this code. Return of this one is eg: "JS John Smith" but when I try to put two names plus surname all I get is a mess. I wish to get when I type eg: "John William Smith" something like this: "JW Smith", anybody know hot to do it?
import java.io.*;
import java.io.BufferedReader;
public class ex54 {
public static void main(String[] args) {
System.out.print("Enter your name: ");
BufferedReader br = new BufferedReader(new InputStreamReader (System.in));
String fullName = null;
try{
fullName = br.readLine();
} catch (IOException ioe) {
System.out.println("Error");
System.exit(1);
}
int spacePos = fullName.indexOf(" ");
// String firstName = fullName.substring(0, spacePos);
// String secondName = fullName.substring(1, spacePos);
String firstInitial = fullName.substring(0, 1);
String secondInitial = fullName.substring(spacePos+1, spacePos+2);
String userName = (firstInitial + secondInitial + " ").concat(fullName);
System.out.println("Hello, your user name is: " + userName);
}
}
}
You can split the name, assuming you are given a three-name string:
String[] names = fullname.split(" ");
System.out.println("" + names[0].charAt(0) + names[1].charAt(0) + " " + names[2]);
int spacePos = -1;
System.out.print("Hello, your user name is:");
do {
System.out.print(" "+fullName.substring(spacePos+1, spacePos+2));
fullName = fullName.substring(spacePos+1);
spacePos = fullName.indexOf(" ");
}while(spacePos != -1);
System.out.println("\b"+fullName);
Just for kicks, here is an implementation using regular expressions:
private static String firstNamesToInitials(String name) {
StringBuilder buf = new StringBuilder();
Matcher m = Pattern.compile("\\b([A-Z])[A-Za-z]*\\b").matcher(name);
String lastName = null;
while (m.find()) {
buf.append(m.group(1));
lastName = m.group();
}
if (buf.length() <= 1)
return lastName;
buf.setCharAt(buf.length() - 1, ' ');
return buf.append(lastName).toString();
}
Test
System.out.println(firstNamesToInitials("Cher"));
System.out.println(firstNamesToInitials("John Smith"));
System.out.println(firstNamesToInitials("John William Smith"));
System.out.println(firstNamesToInitials("Charles Philip Arthur George"));
System.out.println(firstNamesToInitials("Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de la Santísima Trinidad Ruiz y Picasso"));
Output
Cher
J Smith
JW Smith
CPA George
PDFPJNRCTR Picasso

How to divide string into two parts using regex in java?

String strArray="135(i),15a,14(g)(q)12,67dd(),kk,159"; //splited by ','
divide string after first occurrence of alphanumeric value/character
expected output :
original expected o/p
15a s1=15 s2=a
67dd() s1=67 s2=dd()
kk s1="" s2=kk
159 s1=159 s2=""
Please help me................
You could use the group-method of Pattern/Matcher:
String strArray = "135(i),15a,14(g)(q)12,67dd(),kk,159";//splited by ','
Pattern pattern = Pattern.compile("(?<digits>\\d*)(?<chars>[^,]*)");
Matcher matcher = pattern.matcher(strArray);
while (matcher.find()) {
if (!matcher.group().isEmpty()) //omit empty groups
System.out.println(matcher.group() + " : " + matcher.group("digits") + " - " + matcher.group("chars"));
}
The method group(String name) gives you the String found in the pattern's parenthesis with the specific name (here it is 'digits' or 'chars') within the match.
The method group(int i) would give you the String found in the i-th parenthesis of the pattern within the match.
See the Oracle tutorial at http://docs.oracle.com/javase/tutorial/essential/regex/ for more examples of using regex in Java.
You can use a Pattern and a Matcher to find the first index of a letter preceded by a number and split at that position.
Code
public static void main(String[] args) throws ParseException {
String[] inputs = { "15a", "67dd()", "kk", "159" };
for (String input : inputs) {
Pattern p = Pattern.compile("(?<=[0-9])[a-zA-Z]");
Matcher m = p.matcher(input);
System.out.println("Input: " + input);
if (m.find()) {
int splitIndex = m.end();
// System.out.println(splitIndex);
System.out.println("1.\t"+input.substring(0, splitIndex - 1));
System.out.println("2.\t"+input.substring(splitIndex - 1));
} else {
System.out.println("1.");
System.out.println("2.\t"+input);
}
}
}
Output
Input: 15a
1. 15
2. a
Input: 67dd()
1. 67
2. dd()
Input: kk
1.
2. kk
Input: 159
1.
2. 159
Use java.util.regex.Pattern and java.util.regex.Matcher
String strArray="135(i),15a,14(g)(q)12,67dd(),kk,159";
String arr[] = strArray.split(",");
for (String s : arr) {
Matcher m = Pattern.compile("([0-9]*)([^0-9]*)").matcher(s);
System.out.println("String in = " + s);
if(m.matches()){
System.out.println(" s1: " + m.group(1));
System.out.println(" s2: " + m.group(2));
} else {
System.out.println(" unmatched");
}
}
outputs:
String in = 135(i)
s1: 135
s2: (i)
String in = 15a
s1: 15
s2: a
String in = 14(g)(q)12
unmatched
String in = 67dd()
s1: 67
s2: dd()
String in = kk
s1:
s2: kk
String in = 159
s1: 159
s2:
Note how '14(g)(q)12' is not matched. It's not clear what the OP's required output is in this instance (or if a comma is missing from this portion of the example input string).

Categories

Resources