Split with multiple special characters: √(A&B) - java

I have √(A&B)=|C| equation,
after split, I get this value
[√, (, A&B, ),=,|, C,|]
how can get value like this
[√(, A&B, ),=,|, C,|]
This my code,
return teks.split(""
+ "((?<=\\ )|(?=\\ ))|"
+ "((?<=\\!)|(?=\\!))|"
+ "((?<=\\√\\()|(?=\\√\\())|" //this is my problem
+ "((?<=\\√)|(?=\\√))|" //and this
+ "((?<=\\∛)|(?=\\∛))|"
+ "((?<=\\/)|(?=\\|))"
+ "((?<=\\&)|(?=\\&))"
+ "");
}

Try Matcher.find() for following regexp:
String s = "√(A&B)=|C|";
Matcher m = Pattern.compile("("
+ "(√\\()"
+ "|(\\))"
+ "|(\\w(\\&\\w)*)"
+ "|(=)"
+ "|(\\|)"
+ ")").matcher(s);
ArrayList<String> r = new ArrayList<>();
while(m.find())
r.add(m.group(1));
System.out.printf("%s", r.toString());
Result:
[√(, A&B, ), =, |, C, |]
Upd.
Or, if any symbol before parenthesis (except of "=") should be counted as one symbol with that "(":
String s = "√(A&(B&C))=(|C| & (! D))";
Matcher m = Pattern.compile("("
+ "[^\\s=]?\\(" // capture opening bracket with modifier (if any)
// you can replace it with "[√]?\\(", if only
// "√" symbol should go in conjunction with brace
+ "|\\)" // capture closing bracket
+ "|\\w" // capture identifiers
+ "|[=!\\&\\|]" // capture symbols "=", "!", "&" and "|"
+ ")").matcher(s.replaceAll("\\s", ""));
ArrayList<String> r = new ArrayList<>();
while(m.find())
r.add(m.group(1));
System.out.printf("%s -> %s\n", s, r.toString().replaceAll(", ", ",")); // ArrayList joins it's elements with ", ", so, removing extra space
Result:
√(A&(B&C))=(|C| & (! D)) -> [√(,A,&(,B,&,C,),),=,(,|,C,|,&(,!,D,),)]

Related

how to delete empty line and rest of the character in java

I want to delete empty line and rest of the character from my string, I would like to parse particular value alone from the string.
I want this value alone 23243232 from my string, after product price I've have empty line space and again I've some character so I'm using that empty line as delimiter and trying to get product price alone. But I'm getting other values also along with 23243232. Can someone help me to get only 23243232 from this string
String actualResponse = "--sGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArwzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exsGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArw\r\n"
+ "Product-Discription: form-name; productName=\"iPhone\"\r\n" + "Product-Type: Mobile\r\n"
+ "Product-Price: 23243232\r\n" + "\r\n" + "%dsafdfw32.323efaeed\r\n" + "#$#####";
String productPrice = actualResponse.substring(actualResponse.lastIndexOf("Product-Price:") + 15);
System.out.println("Printing product price ..." + productPrice);
String finalString = productPrice.replaceAll(" .*", "");
This is the output I'm getting:
Printing product price ...23243232
%dsafdfw32.323efaeed
#$#####
But I want only 23243232 - this value alone.
Apply Regular Expression for more flexibility.
String content = "--sGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArwzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exsGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArw\r\n"
+ "Product-Discription: form-name; productName=\"iPhone\"\r\n" + "Product-Type: Mobile\r\n"
+ "Product-Price: 23243232\r\n" + "\r\n" + "%dsafdfw32.323efaeed\r\n" + "#$#####";
String re1 = "\\bProduct-Price:\\s"; // Word 1
String re2 = "(\\d+)"; // Integer Number 1
Pattern p = Pattern.compile(re1 + re2, Pattern.DOTALL);
Matcher m = p.matcher(content);
while (m.find()) {
for (int i = 0; i <= m.groupCount(); i++) {
System.out.println(String.format("Group=%d | Value=%s",i, m.group(i)));
}
}
It will print out:
Group=0 | Value=Product-Price: 23243232
Group=1 | Value=23243232
first solution came in my mind. its not the best but will solve your problem.
StringBuilder finalString =new StringBuilder();
for (Character c : productPrice.toCharArray()) {
if(Character.isDigit(c)){
finalString.append(c);
}else{
break;
}
}
This is because you are printing the entire sub-string right from index: actualResponse.lastIndexOf("Product-Price:") + 15 to the end of the string.
You need to provide the end index too as a second parameter in substring method.
You need to use this:
int start = actualResponse.lastIndexOf("Product-Price:") + 15;
int end = actualResponse.indexOf("\r\n", start); // The first "\r\n" from the index `start`
String productPrice = actualResponse.substring(start, end);
This will give your final ans...
String actualResponse ="--sGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArwzoF_yDmmW5DfupJDtuHlh20LL2SAbWZb8a3exzoF_y DmmW5DfupJDtuHlh20LL2SAbWZb8a3exsGEFoZV85Qnkco_QAU5b6B3Tt1OrOOFkArw\r\n"
+ "Product-Discription: form-name; productName=\"iPhone\"\r\n" + "Product-Type: Mobile\r\n"
+ "Product-Price: 23243232\r\n" + "\r\n" + "%dsafdfw32.323efaeed\r\n" + "#$#####";
String productPrice = actualResponse.substring(actualResponse.lastIndexOf("Product-Price:") + 15);
System.out.println("Printing content lenght..." + productPrice.split("\r\n")[0]);

find the particular string that not being trapped between double quotes java regex

I want to find a string (say x) that satisfies two conditions:
matches the pattern \b(x)\b
does not match the pattern ".*?(x).*?(?<!\\)"
In other words, I am looking for a value of x that is a complete word (condition1) and it is not in double quotes (condition2).
" x /" m" not acceptable
" x \" " + x + " except" :only the second x is acceptable.
What Java code will find x?
The first condition is straight forward. To check second condition you will have to check number of valid double quotes. If they are even then the string captured in first condition is valid.
String text = "basdf + \" asdf \\\" b\" + b + \"wer \\\"\"";
String toCapture = "b";
Pattern pattern1 = Pattern.compile("\\b" + toCapture + "\\b");
Pattern pattern2 = Pattern.compile("(?<!\\\\)\"");
Matcher m1 = pattern1.matcher(text);
Matcher m2;
while(m1.find()){ // if any <toCapture> found (first condition fulfilled)
int start = m1.start();
m2 = pattern2.matcher(text);
int count = 0;
while(m2.find() && m2.start() < start){ // count number of valid double quotes "
count++;
}
if(count % 2 == 0) { // if number of valid quotes is even
char[] tcar = new char[text.length()];
Arrays.fill(tcar, '-');
tcar[start] = '^';
System.out.println(start);
System.out.println(text);
System.out.println(new String(tcar));
}
}
Output :
23
basdf + " asdf \" b" + b + "wer \""
-----------------------^-----------

How to match nested repeating groups with regex in Java?

I'm trying to match repeating groups with Java:
String s = "The very first line\n"
+ "\n"
+ "AA (aa)\n"
+ "BB (bb)\n"
+ "CC (cc)\n"
+ "\n";
Pattern p = Pattern.compile(
"The very first line\\s+"
+ "((?<gr1>[a-z]+)\\s+\\((?<gr2>[^)]+)\\)\\s*)+",
Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(s);
if (m.find()) {
for (int i = 0; i <= m.groupCount(); i++) {
System.out.println("group #" + i + ": [" + m.group(i).trim() + "]");
}
System.out.println("group gr1: [" + m.group("gr1").trim() + "]");
System.out.println("group gr2: [" + m.group("gr2").trim() + "]");
}
The problem is with the repeating groups: though the regex matches the whole text block (see group #0 in output example below), when retrieving groups #2 and #3 (or by name as well - gr1/gr2) it does return only the last match (CC/cc) and skips the previous ones (AA/aa and BB/bb)
group #0: [The very first line
AA (aa)
BB (bb)
CC (cc)]
group #1: [CC (cc)]
group #2: [CC]
group #3: [cc]
group gr1: [CC]
group gr2: [cc]
Is there a way to solve this?
edit: The very first line is in the pattern as identification string - see the comment to the gknicker's answer below
It seems like you wanted your pattern to match not the whole input string, but just the individual repeating sections. If that's true, your pattern would be:
Pattern p = Pattern.compile(
"((?<gr1>[a-z]+)\\s+\\((?<gr2>[^)]+)\\))",
Pattern.CASE_INSENSITIVE);
Then in this case you would have a while loop to find each match:
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println("group gr1: ["
+ m.group("gr1").trim() + "]");
System.out.println("group gr2: ["
+ m.group("gr2").trim() + "]");
}
But if you need the whole match, you'll probably have to use two patterns like this:
String s = "The very first line\n"
+ "\n"
+ "AA (aa)\n"
+ "BB (bb)\n"
+ "CC (cc)\n"
+ "\n";
Pattern p = Pattern.compile(
"The very first line\\s+(([a-z]+)\\s+\\(([^)]+)\\)\\s*)+",
Pattern.CASE_INSENSITIVE);
Pattern p2 = Pattern.compile(
"((?<gr1>[a-z]+)\\s+\\((?<gr2>[^)]+)\\))",
Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(s);
while (m.find()) {
Matcher m2 = p2.matcher(m.group());
while (m2.find()) {
System.out.println("group gr1: ["
+ m2.group("gr1").trim() + "]");
System.out.println("group gr2: ["
+ m2.group("gr2").trim() + "]");
}
}

RegEx in java to replace a String

I've been trying to replace this mathematical function x^2*sqrt(x^3) to this pow(x,2)*Math.sqrt(pow(x,3))
so this is the regex
/([0-9a-zA-Z\.\(\)]*)^([0-9a-zA-Z\.\(\)]*)/ pow(\1,\2)
it works in ruby, but I can't find a way to do it in java, I tried this method
String function= "x^2*sqrt(x^3)";
Pattern p = Pattern.compile("([a-z0-9]*)^([a-z0-9]*)");
Matcher m = p.matcher(function);
String out = function;
if(m.find())
{
System.out.println("GRUPO 0:" + m.group(0));
System.out.println("GRUPO 1:" + m.group(1));
out = m.replaceFirst("pow(" + m.group(0) + ", " + m.group(1) + ')');
}
String funcformat = out;
funcformat = funcformat.replaceAll("sqrt\\(([^)]*)\\)", "Math.sqrt($1)");
System.out.println("Return Value :"+ funcion );
System.out.print("Return Value :"+ funcformat );
But still doesn´t work, the output is: pow(x, )^2*Math.sqrt(x^3) as I said before it should be pow(x,2)*Math.sqrt(pow(x,3)).
Thank you!!
As others have commented, regex is not the way to go. You should use a parser. But if you want some quick and dirty:
From Matcher:
Capturing groups are indexed from left to right, starting at one.
Group zero denotes the entire pattern, so the expression m.group(0)
is equivalent to m.group().
So you need to use m.group(1) and m.group(2). And escape the caret ^ in your regex.
import java.util.regex.*;
public class Replace {
public static void main(String[] args) {
String function= "x^2*sqrt(3x)";
Pattern p = Pattern.compile("([a-z0-9]*)\\^([0-9]*)");
Matcher m = p.matcher(function);
String out = function;
if (m.find()) {
System.out.println("GRUPO 0:" + m.group(1));
System.out.println("GRUPO 1:" + m.group(2));
out = m.replaceFirst("pow(" + m.group(1) + ", " + m.group(2) + ')');
}
String funcformat = out;
funcformat = funcformat.replaceAll("sqrt\\(([a-z0-9]*)\\^([0-9]*)]*\\)", "Math.sqrt(pow($1, $2))");
System.out.println("Return Value :"+ function );
System.out.print("Return Value :"+ funcformat );
}
}

Markdown algorithm: string difficulties

I started writing this algorithm:
public static String convert(String str) {
if (str.equals("# "))
return " ";
if (str.matches("#+.+")) {
int n = str.length() - str.replaceFirst("#+", "").length();
return "<h" + n + ">" + str.substring(n) + "<h" + n + ">";
}
return str;
}
}
So when I type, ####title, it returns < h4>title< /h4>
My problem is that when I write ####title###title, I would like it to return < h4>title< /h4> < h3>title< /h3> but it only returns < h4>title< /h4>...What am I doing wrong???
Thats because you are using the pattern: - #+.+.
Now, since . matches everything in Regex, so in the above pattern, it matches everything after an initial set of #'s.
So, for your input: - ####title###title, your pattern will match: -
#+ will match ####
.+ will match title###title
You need to change your regex to : - (#+[^#]+), and probably need to use Pattern class here to get the desired output, becaues you want to match every part of your string to the given pattern.
#+[^#]+ -> Will match the first set of # and then everything after that, except #. So it stops where the next set of #'s start.
Here's how you can use it: -
String str = "####title###title"; // str is the method parameter
if (str.equals("# "))
System.out.println(" ");
Pattern pattern = Pattern.compile("(#+[^#]+)");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
String str1 = matcher.group(1);
int n = str1.length() - str1.replaceFirst("#+", "").length();
System.out.println("<h" + n + ">" + str1.substring(n) + "</h" + n + ">");
}
OUTPUT: -
<h4>title</h4>
<h3>title</h3>
You are matching wrong string, try this one:
#+[^#]+
And of course you want to make call it recursivly or in a loop
You are replacing only the first occurrence of #+. Try replacing the if with a while and instead of return inside the if, append the result into a StringBuilder.
Something like:
String str = "####title###title2";
StringBuilder sb = new StringBuilder();
while (str.matches("#+.+")) {
int n = str.length() - str.replaceFirst("#+", "").length();
str = str.replaceFirst("#+", "");
int y = str.length();
if(str.matches(".+#+.+")) {
y = str.indexOf("#");
sb.append( "<h" + n + ">" + str.substring(0,y) + "<h" + n + ">");
str = str.substring(y, str.length());
} else {
sb.append( "<h" + n + ">" + str.substring(0,y) + "<h" + n + ">");
}
}
System.out.println(sb.toString());
}

Categories