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
Related
I have the following sentence:
"these were: s1, which has the a domain active site mutated to agha;
s2, which has the a domain active site mutated to agha; and bm, which
has three point mutations (i272a, d346a and d348a) within the b domain
that prevent substrate binding [15]."
My objective is to get the codes between parenthesis as a group, which is the following:
(i272a, d346a and d348a)
So how i can do that using any other way in java with having a consideration that those codes could be separated by conjunctions such as "and" or "or"?
The expected result should look like this as it is stored in a map:
index=27 , value=i272a
index=37 , value=d346a
index=47 , value=d348a
note: the index is not the right index where the code starts from in the sentence.
As spgodara already said, you can solve this problem using a regular expression. In Java, you can use the class Pattern for this. To better understand regular expressions in Java, have a look at the website RegexPlanet. Here is an example how to solve your problem:
package stackoverflow;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExample {
private static Pattern outerPattern = Pattern.compile("[^\\(]*(\\([^\\)]*\\))[^\\(]*");
private static Pattern innerPatter = Pattern.compile("\\(([^\\s\\),]+)|,\\s+([^\\s\\),]+)|([^\\s\\),]+)\\)");
public static void main(String[] args) {
List<List<String>> outerResult = new ArrayList<List<String>>();
String input = "foo (a1, a2, a3, a4 and a5) bar (b1, b2 and b3) more (c1 or c2) ignored (d1, d2) text (e1) the end";
Matcher outerMatcher = outerPattern.matcher(input);
while (outerMatcher.find()) {
outerResult.add(processOuter(outerMatcher));
}
System.out.println(outerResult);
}
private static List<String> processOuter(Matcher outerMatcher) {
List<String> innerResult = new ArrayList<String>();
Matcher innerMatcher = innerPatter.matcher(outerMatcher.group(1));
while (innerMatcher.find()) {
innerResult.add(processInner(innerMatcher));
}
return innerResult;
}
private static String processInner(Matcher innerMatcher) {
for (int i = 1; i <= innerMatcher.groupCount(); i++) {
String group = innerMatcher.group(i);
if (group != null) {
return group;
}
}
return null;
}
}
Output:
[[a1, a2, a3, a4, a5], [b1, b2, b3], [c1, c2], [d1, d2], [e1]]
Also, use these links to better understand the example above:
outerPattern on RegexPlanet
innerPattern on RegexPlanet
Note however, that you might need to adjust the regex to really match your use case.
use this simple regex pattern;
Pattern pattern = Pattern.compile("\\((i\\d+\\w),\\s(d\\d+\\w)\\s\\w+\\s(d\\d+\\w)");
The Output is as follows
i272a
d346a
d348a.
i hope this helps. If you want the full program, you can request for it.Would be glad to give it to you
how can I check to make sure the only special character a string can have is a comma?
testString = "123,34565,222" //OK
testString = "123,123.123." //Fail
A full working example based on #Simeon's regex. This reuses a single Matcher object, which is recommended if the check will be done frequently.
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class OnlyLettersDigitsCommas {
//"": Dummy search string, to reuse matcher
private static final Matcher lettersCommasMtchr = Pattern.
compile("^[a-zA-Z0-9,]+$").matcher("");
public static final boolean isOnlyLettersDigitsCommas(String to_test) {
return lettersCommasMtchr.reset(to_test).matches();
}
public static final void main(String[] ignored) {
System.out.println(isOnlyLettersDigitsCommas("123,34565,222"));
System.out.println(isOnlyLettersDigitsCommas("123,123.123."));
}
}
Output:
[C:\java_code\]java OnlyLettersDigitsCommas
true
false
You can use a quick String.contains method like this:
if ( testString.contains(".") {
// fails
}
But I would consider using Regex for this type of validation.
EDIT : As stated in the comments of the question : [a-zA-Z0-9,]
Maybe a
if (!testString.matches("^[a-zA-Z0-9,]+$")) {
// throw an exception
}
check ?
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.
I have a requirement where in I want to get two different items form one long string.
I have got below program where in I get required items when I do group(1) and group(6).
But I want to get it in group(1) and group(2).
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExample {
public static void main(String args[]) {
String somepattern = "((123|456)-(0|1)-((\\d-?){8})-\\d{1})/(\\d{2})";
String str = "/somethingwaste/123-0-1234-5678-9/10";
Matcher p = Pattern.compile(somepattern).matcher(str);
while (p.find()) {
System.out.println(p.group(1));
System.out.println(p.group(6));
}
Any pointers directions appriciated.
Thanks
This should do it
String somepattern = "((?:123|456)-[01]-(?:\\d-?){8}-\\d)/(\\d{2})";
The ?: makes a () non-capturing.
Just make the groups you don't want to keep non-capturing using ?::
String somepattern = "((?:123|456)-[01]-(?:\\d-?){8}-\\d)/(\\d{2})";
String str = "/somethingwaste/123-0-1234-5678-9/10";
Matcher p = Pattern.compile(somepattern).matcher(str);
while (p.find()) {
System.out.println(p.group(1));
System.out.println(p.group(2));
}
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....