I have a string:
2 + 2 = ${2 + 2}
This is a ${"string"}
This is an object: ${JSON.stringify({a: "B"})}
This should be "<something>": ${{
abc: "def",
cba: {
arr: [
"<something>"
]
}
}.cba.arr[0]}
This should ${"${also work}"}
And after parsing it I should get something like that:
2 + 2 = 4
This is a string
This is an object: {"a":"B"}
This should be "<something>": <something>
This should ${also work}
So I need help implementing it in Java, I simply need to get what is between ${ and }.
I tried using a regular expression: \${(.+?)} but it fails when string inside contains }
So after a bit of testing, I've ended up with this:
ScriptEngine scriptEngine = new ScriptEngineManager(null).getEngineByName("JavaScript");
String str = "2 + 2 = ${2 + 2}\n" +
"This is a ${\"string\"}\n" +
"This is an object: ${JSON.stringify({a: \"B\"})}\n" +
"This should be \"F\": ${var test = {\n" +
" a : {\n" +
" c : \"F\"\n" +
" }\n" +
"};\n" +
"test.a.c\n" +
"}\n" +
"This should ${\"${also work}\"}"; // String to be parsed
StringBuffer result = new StringBuffer();
boolean dollarSign = false;
int bracketsOpen = 0;
int beginIndex = -1;
int lastEndIndex = 0;
char[] chars = str.toCharArray();
for(int i = 0; i < chars.length; i++) { // i is for index
char c = chars[i];
if(dollarSign) {
if(c == '{') {
if(beginIndex == -1) {
beginIndex = i + 1;
}
bracketsOpen++;
} else if(c == '}') {
if(bracketsOpen > 0) {
bracketsOpen--;
}
if(bracketsOpen <= 0) {
int endIndex = i;
String evalResult = ""; // evalResult is the replacement value
try {
evalResult = scriptEngine.eval(str.substring(beginIndex, endIndex)).toString(); // Using script engine as an example; str.substring(beginIndex, endIndex) is used to get string between ${ and }
} catch (ScriptException e) {
e.printStackTrace();
}
result.append(str.substring(lastEndIndex, beginIndex - 2));
result.append(evalResult);
lastEndIndex = endIndex + 1;
dollarSign = false;
beginIndex = -1;
bracketsOpen = 0;
}
} else {
dollarSign = false;
}
} else {
if(c == '$') {
dollarSign = true;
}
}
}
result.append(str.substring(lastEndIndex));
System.out.println(result.toString());
Related
I want to identify whether my string contains any hex code or not.
Use cases
String input1 = "hello check this input ";
String input2 = "hello check 0x740x680x690x73 input";
String input3 = "0x680x650x6c0x6c0x6f0x200x630x680x650x630x6b0x200x740x680x690x730x200x690x6e0x700x750x74";
isContainHex(input1) should return false
isContainHex(input2) should return true
isContainHex(input3) should return true
I have tried
String input2 = "hello check 0x740x680x690x73 input";
if(input2.contains("0x") || input2.contains("\\x"))
{
System.out.println("string contains hex");
}
and I am able to find hex but,
If My input contains hex like
String input4 = "h68h65h6ch6ch6f check this input ";
Here I cant check input4.contains("h")
Any one have solution for this?
is there any standard library by which I can achive same?
Update
I have wrote following code, and its working well but taking time.
Now can it be optimize
try
{
if (input != null && input.trim().length() > 0)
{
String originalHex = null;
StringBuilder output = new StringBuilder();
String inputArray[] = null;
if (StringUtils.countMatches(input, "\\x") > 3)
{
originalHex = input.substring(input.indexOf("\\x"), input.lastIndexOf("\\x", input.length()) + 4);
inputArray = input.split("\\Q\\x\\E");
}
else if (StringUtils.countMatches(input, "0x") > 3)
{
originalHex = input.substring(input.indexOf("0x"), input.lastIndexOf("0x", input.length()) + 4);
inputArray = input.split("0x");
}
if (inputArray != null && inputArray.length > 0)
{
for (String str: inputArray)
{
int strLength = str.trim().length();
if (strLength == 2)
{
output.append((char)Integer.parseInt(str, 16));
}
else if (strLength > 2)
{
if (strLength % 2 != 0)
{
strLength = strLength - 1;
}
for (int i = 0; i < strLength; i += 2)
{
String val = str.substring(i, i+2);
if (val.matches("\\d+"))
{
output.append((char)Integer.parseInt(val, 16));
}
}
}
}
input = input.replaceAll("\\Q" + originalHex + "\\E", output.toString());
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
syso(input);
I've been trying to work on this problem for a while now but to no avail. When I run the code I get this error message: incompatible types: edu.duke.StorageResource cannot be converted to java.lang.String on line String geneList = FMG.storeAll(dna);. Does this mean I'm trying to make edu.duke object work with a java.lang.String type object? What would we go about resolving this issue?
Here's my code so far:
package coursera_java_duke;
import java.io.*;
import edu.duke.FileResource;
import edu.duke.StorageResource;
import edu.duke.DirectoryResource;
public class FindMultiGenes5 {
public int findStopIndex(String dna, int index) {
int stop1 = dna.indexOf("TGA", index);
if (stop1 == -1 || (stop1 - index) % 3 != 0) {
stop1 = dna.length();
}
int stop2 = dna.indexOf("TAA", index);
if (stop2 == -1 || (stop2 - index) % 3 != 0) {
stop2 = dna.length();
}
int stop3 = dna.indexOf("TAG", index);
if (stop3 == -1 || (stop3 - index) % 3 != 0) {
stop3 = dna.length();
}
return Math.min(stop1, Math.min(stop2, stop3));
}
public StorageResource storeAll(String dna) {
//CATGTAATAGATGAATGACTGATAGATATGCTTGTATGCTATGAAAATGTGAAATGACCCAdna = "CATGTAATAGATGAATGACTGATAGATATGCTTGTATGCTATGAAAATGTGAAATGACCCA";
String geneAL = new String();
String sequence = dna.toUpperCase();
StorageResource store = new StorageResource();
int index = 0;
while (true) {
index = sequence.indexOf("ATG", index);
if (index == -1)
break;
int stop = findStopIndex(sequence, index + 3);
if (stop != sequence.length()) {
String gene = dna.substring(index, stop + 3);
store.add(gene);
//index = sequence.substring(index, stop + 3).length();
index = stop + 3; // start at the end of the stop codon
}else{ index = index + 3;
}
}
return store;//System.out.println(sequence);
}
public void testStorageFinder() {
DirectoryResource dr = new DirectoryResource();
StorageResource dnaStore = new StorageResource();
for (File f : dr.selectedFiles()) {
FileResource fr = new FileResource(f);
String s = fr.asString();
dnaStore = storeAll(s);
printGenes(dnaStore);
}
System.out.println("size = " + dnaStore.size());
}
public String readStrFromFile(){
FileResource readFile = new FileResource();
String DNA = readFile.asString();
//System.out.println("DNA: " + DNA);
return DNA;
}//end readStrFromFile() method;
public float calCGRatio(String gene){
gene = gene.toUpperCase();
int len = gene.length();
int CGCount = 0;
for(int i=0; i<len; i++){
if(gene.charAt(i) == 'C' || gene.charAt(i) == 'G')
CGCount++;
}//end for loop
System.out.println("CGCount " + CGCount + " Length: " + len + " Ratio: " + (float)CGCount/len);
return (float)CGCount/len;
}//end of calCGRatio() method;
public void printGenes(StorageResource sr){
//create a FindMultiGenesFile object FMG
FindMultiGenes5 FMG = new FindMultiGenes5();
//read a DNA sequence from file
String dna = FMG.readStrFromFile();
String geneList = FMG.storeAll(dna);
//store all genes into a document
StorageResource dnaStore = new StorageResource();
System.out.println("\n There are " + geneList.size() + " genes. ");
int longerthan60 = 0;
int CGGreaterthan35 = 0;
for(int i=0; i<geneList.size(); i++){
if(!dnaStore.contains(geneList.get(i)))
dnaStore.add(geneList.get(i));
if(geneList.get(i).length() > 60) longerthan60++;
if(FMG.calCGRatio(geneList.get(i)) > 0.35) CGGreaterthan35++;
}
System.out.println("dnaStore.size: " + dnaStore.size());
System.out.println("\n There are " + dnaStore.size() + " genes. ");
System.out.println("There are " + longerthan60 + " genes longer than 60.");
System.out.println("There are " + CGGreaterthan35 + " genes with CG ratio greater than 0.35.");
}//end main();
}
I found your post as I am also doing a similar course at Duke using those edu.duke libraries.
When I get that error message it is because I'm using the wrong method to access it.
Try FMD.data() to get an iterable of all of the gene strings.
I am trying to build a string recursively but it isn't quite working
my code looks like this
public void UpdatePrintList(ArrayList<Node> closedList, ArrayList<Node> openList)
{
if(count <= iterations)
{
String line1 = "";
for(int i = 0; i < closedList.size(); i++)
{
if(i > 0)
{
line1 = line1 + "-";
}
line1 = line1 + closedList.get(i).GetMovement();
}
line1 = line1 + " " + closedList.get(closedList.size()-1).GetG() + " " + closedList.get(closedList.size()-1).GetHeuristic() + " " + closedList.get(closedList.size()-1).GetF();
printList.add(line1);
//*****************************************************************
String line2 = "OPEN ";
for(int i = 0; i < openList.size(); i++)
{
line2 = FindEarlierNode(openList.get(i), line2);
}
System.out.println(line2);
}
count++;
}
private String FindEarlierNode(Node varNode, String varString)
{
if(varNode.OpenedBy() == null)
{
varString += varNode.GetMovement() + "-";
}
else
{
FindEarlierNode(varNode.OpenedBy(), varString);
}
varString = varString + varNode.GetMovement() + "-";
return varString;
}
The strange thing is that I know that this if statement
if(varNode.OpenedBy() == null)
{
varString += varNode.GetMovement() + "-";
}
runs correctly, so the function does reach the earliest node. But it doesnt add to the string. The code runs but returns nothing. GetMovement just returns a one or two character string. The output should look like this:
OPEN S-R S-RD S-D
But instead it looks like this:
OPEN D-DL-L-
Can anyone help?
Managed to work it out. This gives me my desired output:
private String FindEarlierNode(Node varNode, String varString)
{
if(varNode.OpenedBy() != null)
{
varString = varString + varNode.GetMovement() + "-";
return FindEarlierNode(varNode.OpenedBy(), varString);
}
return varString += varNode.GetMovement() + " ";
}
thanks everyone.
I have 2 string which I want to join as per my requirements. Say I have
String sa = {"as,asd,asdf"};
String qw = {"12,123,1234"};
String[] separated = ItemSumm.split(",");
String[] separateds = Itemumm.split(",");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < separateds.length; i++)
{
if (separated.length == i + 1)
{
sb.append(separated[i] + "(" + separateds[i] + ")");
} else
{
sb.append(separated[i] + "(" + separateds[i] + "),");
}
}
deleteListItem.list_summ.setText(sb.toString());
it gives as(12),asd(123),asdf(1234)
But problem is , it can be like
String sa = {"as,asdf"};
String qw = {"12,123,1234"};
So in this I want like
as(12),asdf(123),1234
Try this code :
String sa = {"as,asd"};
String qw = {"12,123,1234"};
String[] separated = ItemSumm.split(",");
String[] separateds = Itemumm.split(",");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < separateds.length; i++) {
if (separated.length == i + 1) {
if(separated.length == i) {
sb.append(separateds[i] + "");
} else {
sb.append(separated[i] + "(" + separateds[i] + ")");
}
} else {
if(separated.length == i) {
sb.append("," + separateds[i]);
} else {
sb.append(separated[i] + "(" + separateds[i] + "),");
}
}
}
deleteListItem.list_summ.setText(sb.toString());
// Answer : as(12),asd(123),1234
String sa = {"as,asd,asdf"};
String qw = {"12,123,1234"};
String[] separated = ItemSumm.split(",");
String[] separateds = Itemumm.split(",");
StringBuffer sb = new StringBuffer();
// first loop through separated, starting with a comma
for (int i = 0; i < separated.length; i++) {
sb.append(",").append(separated[i]).append("(").append(separateds[i]).append(")"));
}
// append remaining items in separateds
for (int i = separated.length; i < separateds.length; i++) {
sb.append(",").append(separateds[i]);
}
deleteListItem.list_summ.setText(sb.toString().substring(1)); // remove starting comma
if the lenghts of the strings are the sa, do the join
if (separated.length == i + 1 && (separated[i].lenght == separateds[i].lenght))
I get the HTML Javascript string such as :
htmlString = "https\x3a\x2f\x2ftest.com"
But I want to decode it as below :
str = "https://test.com"
That means , I want a Util API like :
public static String decodeHex(String htmlString){
// do decode and converter here
}
public static void main(String ...args){
String htmlString = "https\x3a\x2f\x2ftest.com";
String str = decodeHex(htmlString);
// str should be "https://test.com"
}
Does anybody know how to implement this API - decodeHex ?
This should be enough to get you started. I leave implementing hexDecode and sorting out malformed input as an exercise for you.
public String decode(String encoded) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < encoded.length(); i++) {
if (encoded.charAt(i) == '\' && (i + 3) < encoded.length() && encoded.charAt(i + 1) == 'x') {
sb.append(hexDecode(encoded.substring(i + 2, i + 4)));
i += 3;
} else {
sb.append(encoded.charAt(i));
}
}
return sb.toString;
}
public String decode(String encoded) throws DecoderException {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < encoded.length(); i++) {
if (encoded.charAt(i) == '\\' && (i + 3) < encoded.length() && encoded.charAt(i + 1) == 'x') {
sb.append(new String(Hex.decodeHex(encoded.substring(i + 2, i + 4).toCharArray()),StandardCharsets.UTF_8));
i += 3;
} else {
sb.append(encoded.charAt(i));
}
}
return sb.toString();
}