Splitting String into Array of Strings Java - java

I have a String that looks like this
The#red#studio#502#4
I need to split it into 3 different Strings in the array to be
s[0] = "The red studio"
s[1] = "502"
s[2] = "4"
The problem is the first one should have only words and the second and third should have only numbers...
I was trying to play with the s.split() Method, but no luck.

String s= "The#red#studio#502#4";
String[] array = s.split("#(?=[0-9])");
for(String str : array)
{
System.out.println(str.replace('#',' '));
}
Output:
The red studio
502
4
Ideone link.

I've decided to edit out my impl because I think that #Srinivas's is more elegant. I'm leaving the rest of my answer though because the tests are still useful. It passes on #Srinivas's example too.
package com.sandbox;
import com.google.common.base.Joiner;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class SandboxTest {
#Test
public void testQuestionInput() {
String[] s = makeResult("The#red#studio#502#4");
assertEquals(s[0], "The red studio");
assertEquals(s[1], "502");
assertEquals(s[2], "4");
}
#Test
public void testAdditionalRequirement() {
String[] s = makeResult("The#red#studio#has#more#words#502#4");
assertEquals(s[0], "The red studio has more words");
assertEquals(s[1], "502");
assertEquals(s[2], "4");
}
private String[] makeResult(String input) {
// impl inside
}
}

Simply try:
'String s[]= yourString.split("#")' it will return string array....

Related

JUnit - How to test the main method that takes a user input and prints a result accordingly?

I have a calculator that takes input and prints result. For example:
Input to scanner:
2+3+4=
Prints:
9.00
I want to test this main method in JUnit. This is how far I came so far (Operator is the class):
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import org.junit.Before;
import org.junit.jupiter.api.Test;
class MainTester {
private final ByteArrayOutputStream resultByte = new ByteArrayOutputStream();
private final PrintStream result = System.out;
#Before
public void setUp() {
System.setOut(new PrintStream(resultByte));
}
#Test
void test() {
Operator operator = new Operator();
String input = "2+3+4=";
InputStream in = new ByteArrayInputStream(input.getBytes());
System.setIn(in);
String[] args = null;
System.out.println(operator.main(args));
assertEquals("9.00", resultByte.toString());
}
}
Testing is much easier if you separate responsibilities. E.g. the part that computes the result should not be the same as the one that is reading the input and printing the output. If Operator had a method compute, that takes a String with the input ("2+3+4") and returns a String with the result ("9.00"). You can then test that this method returns the expected result. Your main method would then read the input pass it to compute and print the result.
Something along these lines:
String result = operator.compute("2+3+4");
assertEquals(result, "9.00");

Does java support duplicate subpattern group number in regex?

I am trying to get a single match with regex which contains both parts of the string at once like "BERPAR" in the following text:
{"from":"BER", "comment":"something", "to":"PAR" }
I came up with this (?|from":"([A-Z]{3})"|to":"([A-Z]{3})"), which apparently works fine with PCRE as you can see here
But in the code, I get an error with Java compiler.
Exception in thread "main" java.util.regex.PatternSyntaxException: Unknown inline modifier near index 2
(?|from":"([A-Z]{3})"|to":"([A-Z]{3})")
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.List;
import java.util.ArrayList;
public class HelloWorld{
public static void main(String []args){
String str = "{\"from\":\"BER\", \"comment\":\"something\", \"to\":\"PAR\" }";
System.out.println(str);
Pattern p = Pattern.compile("(?|from\":\"([A-Z]{3})\"|to\":\"([A-Z]{3})\")");
Matcher m = p.matcher(str);
List<String> results = new ArrayList<>();
while(m.find()) {
results.add(m.group(1));
}
System.out.println(results);
}
}
link to the online ide to see the error: http://tpcg.io/DWoebEWG
any solution or workaround would be appreciated.
Please note that the objective is Only use regex. It's first matching group should return "BERPAR"
PLEASE NOTE THAT THIS REGEX IS SUPPOSED TO BE PARSED BY A JAVA APPLICATION I DO NOT HAVE ANY OPTION TO WRITE JAVA CODE FOR IT!
THE ABOVE CODE SNIPPET IS FOR DEMONSTRATION PURPOSE ONLY!
Please note that the objective is Only use regex. It's first matching
group should return "BERPAR"
You can get it by using ((?<=from\":\")|(?<=to\":\"))([A-Z]{3})(?=\") as the regex.
Demo:
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HelloWorld {
public static void main(String[] args) {
String str = "{\"from\":\"BER\", \"comment\":\"something\", \"to\":\"PAR\" }";
System.out.println(str);
Pattern p = Pattern.compile("((?<=from\":\")|(?<=to\":\"))([A-Z]{3})(?=\")");
Matcher m = p.matcher(str);
List<String> results = new ArrayList<>();
while (m.find()) {
results.add(m.group());
}
System.out.println(results);
// Join the strings of the list
String joined = String.join("", results);
System.out.println(joined);
}
}
Output:
{"from":"BER", "comment":"something", "to":"PAR" }
[BER, PAR]
BERPAR

java compiler, finding the follow producing duplicates

ive been working on a java compiler assignment that is asking to find the First of a grammar. I have it all ready and done. all the work has been done , but i have one problem. my first is producing duplicates. for example part of my output is this
NonTerminal First
P int void
L int void
D int void
Vd int void
Ts int void
Fn int void
Ps int void void
Ps int void void , the 2nd void is a duplicate. how would i go about removing these duplicates? ill paste my main compiler code were everything happens below.
i suspect i would have to make a change somewere in the findFirst method, since thats were all the action happens , but im not sure what to do.
package compilerproject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.security.KeyStore.Entry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Compiler {
public static void main(String[] args) {
List<Grammar> gList = getGrammar();
Map<String, List<String>> fList = firstList(gList);
//firstlist returns a hash map LHS and RHS
//save it into fList which is a map of Strings and List so u can use it in findFirst method
printFirstList(fList, gList);
ParserLibrary idList = new ParserLibrary();
}
public static List<String> findFirst(String v, List<Grammar> l)
{
List<String> First = new ArrayList<String>();
for(int i = 0; i < l.size(); i++)
{
if(v.equals(l.get(i).term))
{
String [] s = l.get(i).prod.split(" ");
if(!isNonTerm(s[0]))// is a terminal
{
First.add(s[0]);
}
// if the rhs is a terminal
It would save some troubles using a Set instead of a List.
I kept List as return type, but changed the rest.
public static List<String> findFirst(String v, List<Grammar> l) {
Set<String> first = new TreeSet<>();
Set<String> done = new HashSet<>();
done.add(v);
Grammer previous = null;
for (Grammar gr : l) {
if (v.equals(gr.term)) {
String s = gr.prod.split(" ")[0];
if (!isNonTerm(s)) { // is a terminal
first.add(s);
}
// if the rhs is a terminal
if (s.equalsIgnoreCase("empty") && previous != null) {
String[] stemp = previous.prod.split(" ");
if (v.equalsIgnoreCase(stemp[0]) && stemp.length > 1
&& done.add(stemp[1])) {
first.addAll(findFirst(stemp[1], l)); // <--------- Here it happened
}
//if the rhs is empty , then get the previous grammar
//split it.
//find the first of it and ad it to the first list
}
if (!v.equals(s) && isNonTerm(s) && done.add(s)) {
first.addAll(findFirst(s, l));
}
}
previous = gr;
}
return new ArrayList<String>(first);
}
I still do not find the code entirely clear. So maybe with Set at your disposal, you may find a simpler formulation. To remove the scroll bar I place the open brace on the same line.
To prevent endless recursion I added the set done which "evidently" is not needed.

Why is my ArrayList Empty?

I am working on Project Euler problem 13. ( https://projecteuler.net/problem=13 ) The file "Large_Num_List.txt" is the list provided by the project Euler with each number on its own line with a quote mark at the beginning and end of each line. The statement bial.isEmpty() returns true. Why is this happening? (I suspect because this is my first time using Scanner to read a text file.)
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.ArrayList;
import java.math.BigInteger;
import java.util.Iterator;
public class LargeSumTwo
{
public static void main(String[] args)
{
ArrayList<BigInteger> bial = new ArrayList<BigInteger>();
File file = new File("Large_Num_List.txt");
try
{
Scanner scan = new Scanner(file);
while(scan.hasNextBigInteger())
{
bial.add((BigInteger) scan.nextBigInteger());
}
scan.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
System.out.println(bial.isEmpty());
BigInteger answer = new BigInteger("0");
Iterator<BigInteger> iter = bial.iterator();
while(iter.hasNext())
{
answer.add(iter.next());
}
System.out.println(answer);
}
}
You need to strip the quotes first. hasNextBigInteger() will only return true if Scanner can parse a BigInteger. The quotes around the numbers will cause hasNextBigInteger() to return false.
JavaDoc: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#hasNextBigInteger%28%29
Should you add BigInteger in this way:
while(iter.hasNext())
{
answer = answer.add(iter.next());
}
as BigDecimal numbers are immutable?

Regex pattern to replace ampersand with special character

I need to replace https://9S&Re with https://9S#Re so that I can avoid split logic. My objective is it get key as "user_image" and value as "https://9S&Re". But when I use split with '&' it gives me wrong results. So I am trying for regex pattern which will check between &*& if there is not equals inbetween means there is an ampersand symbol in the one of the query value. Any help is really appreciated.
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
public class OAuthTest {
public static void main(String[] args) {
try {
//HashMap paramHashMap=new HashMap();
List<NameValuePair> args2= URLEncodedUtils.parse("tool=canvas&tool_guid=8314&user_image=https://9S&Re&launch_presentation_document_target=iframe", Charset.forName("UTF-8"));
for (NameValuePair arg:args2)
System.out.println(arg.getName()+"="+arg.getValue().replaceAll("#","&"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
In the for loop, are you trying to replace & with #? Your arguments are switched.

Categories

Resources