As input parameters I can have two types of String:
codeName=SomeCodeName&codeValue=SomeCodeValue
or
codeName=SomeCodeName
without codeValue.
codeName and codeValue are the keys.
How can I use regular expression to return the key's values? In this example it would return only SomeCodeName and SomeCodeValue.
I wouldn't bother with a regex for that. String.split with simple tokens ('&', '=') will do the job.
String[] args = inputParams.split("&");
for (String arg: args) {
String[] split = arg.split("=");
String name = split[0];
String value = split[1];
}
Consider using Guava's Splitter
String myinput = "...";
Map<String, String> mappedValues =
Splitter.on("&")
.withKeyValueSeparator("=")
.split(myinput);
The simple way is to split the source string first and then to run 2 separate regular expressions against 2 parts.
Pattern pCodeName = Pattern.compile("codeName=(.*)");
Pattern pCodeValue = Pattern.compile("codeValue=(.*)");
String[] parts = str.split("\\&");
Matcher m = pCodeName.matcher(parts[0]);
String codeName = m.find() ? m.group(1) : null;
String codeValue = null;
if (parts.length > 1) {
m = pCodeValue.matcher(parts[1]);
codeValue = m.find() ? m.group(1) : null;
}
}
But if you want you can also say:
Pattern p = Pattern.compile("codeName=(\\w+)(\\&codeValue=(\\w+))?");
Matcher m = p.matcher(str);
String codeName = null;
String codeValue = null;
if (m.find()) {
codeName = m.group(1);
codeValue = m.groupCount() > 1 ? m.group(2) : null;
}
Related
I am coding in java and I have string like this [A⋈ (B⋈C)]⋈[D⋈ (E⋈F)] I want to split it in a way that I get (B⋈C) in different sub string and (E⋈F) in different string.How can I do that?
I try to do it by regex and string split but it do not work for me.
String[] items = str.split(Pattern.quote("(?=-)"));
ArrayList<String> itemList = new ArrayList<String>();
for (String item : items)
{
itemList.add(item);
}
System.out.println(itemList);
You can this Regex: "\\([A-Za-z⋈]*\\)"
String mData = "[A⋈ (B⋈C)]⋈[D⋈ (E⋈F)] ";
Pattern pattern = Pattern.compile("\\([A-Za-z⋈]*\\)");
Matcher m = pattern.matcher(mData);
while (m.find()) {
System.out.println(mData.substring(m.start(), m.end()));
}
I think it should work : Try this regex "(.{3})"
I'm currently working on some stuff with regex and struggel alot with regex latetly.
I wanted to build some script engine, for that I need to load some presets:
example:
create <Type> [after;before;at;between(2);<Integer>, <DateTime>, <Date>, <Time>, <String>] : Creator
edit <Type> [after;before;at;between(2);<Integer>, <DateTime>, <Date>, <Time>, <String>]
run [<File>, <Command>]
So I want to make sure I can read <Type> [after;before;at;between(2);<Integer>, <DateTime>, <Date>, <Time>, <String>] and [<File>, <Command>].
For the understanding:
NAME <IMPORTANT_PARAMETER> [TEXT_PARAMETER(AMOUNT_OF_OPTIONAL_PAREMETER);<OPTIONAL_PARAMETER(S)>].
In this example I used 'command names' as IMPORTANT_PARAMETER.
For the first rule I made this regex: \<(\w+)\>(?:\s+\[(?:(.*;))(.*)\])?(?:\s+\:\s+(\w+))? and it kinda works within my code:
Pattern p = Pattern.compile("\\<(\\w+)\\>(?:\\s+\\[(?:(.*;))(.*)\\])?(?:\\s+\\:\\s+(\\w+))?");
Matcher m = p.matcher(parameters);
if(m.matches()){
Command command2 = new Command(command);
command2.addParameter(new Parameter(m.group(1)));
String text = m.group(2);
String[] texts = null;
if(text != null){
texts = text.split(";");
command2.addTexts(Arrays.asList(texts));
}
String type = m.group(3);
String[] types = null;
if(type != null){
types = type.split(", ");
for (String string : types) {
Pattern pTypes = Pattern.compile("\\<(?:(\\w+))\\>");
Matcher mTypes = pTypes.matcher(string);
if(mTypes.matches()){
command2.addParameter(new Parameter(mTypes.group(1), true));
}
}
}
String className = m.group(4);
if(className != null){
command2.addClassName(className);
}
commandslist.add(command2);
}
I tried to use \[\<(\w+)\>(?:,\s+\<(\w+)\>)+\] but it only worked for two entries -> example run [<File>, <Command>]. It would be better having a "list" of those optional elements [<File>, <Command>]. So in the end I want to have m.group(1) = File; m.group(2) = Command; m.group(3) = blablabla; and so on.
I hope I could show you my problem good enough, hit me with questions if there is anything more to explain.
Here is a link to the regexr: REGEXR or regex101: REGEX101
Thanks for helping :)
My suggestion is to match the stuff between the words you are after:
public static void main (String[] args) {
final String STR1 = "run [<File>, <Command1>, <Command2>, <Command3>]";
final String STR2 = "run [<File>, <Command1>, <Command2>, <Command3>, <Command4>]";
System.out.println(parse(STR1));
System.out.println(parse(STR2));
}
private static List parse(String str) {
List<String> list = new ArrayList<>();
Pattern p = Pattern.compile("(?:\\G,\\s+|^run\\s+\\[(?:<\\w+>,\\s+)+?)<(\\w+)>");
Matcher m = p.matcher(str);
while (m.find()) {
list.add(m.group(1));
}
return list;
}
which results in the output:
[Command1, Command2, Command3]
[Command1, Command2, Command3, Command4]
Assume that I am given a regex pattern, whole_pattern
Pattern p = Pattern.compile(whole_pattern);
Matcher m = p.matcher(line);
if (m.find()) {
String s1 = m.group(1);
String s2 = m.group(2);
}
Obviously, we can get matched string of each group. But can we get the pattern of each group in the whole_pattern string? For example if whole_pattern = (\\d+)(\\w+), then patterns of group 1 and group 2 are \\d+ and \\w+, respectively.
You can use regexp for regexp:
public void simpleTest() {
String whole_pattern = "(\\d+)(\\w+)";
System.out.println(patternGroups(whole_pattern));
}
private List<String> patternGroups(String patternString) {
List<String> result = new ArrayList<>();
String pattern = "\\(([^()]+)\\)";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(patternString);
while (m.find()) {
result.add(m.group(1));
}
return result;
}
Output of simpleTest() call will be:
[\d+, \w+]
Split your pattern string by ) and remove the first character in each elementh of the resulting array.
I have a string test in which I can see VD1 and and VD2.
How can I extract the value of VD1 and VD2 and store it in string.
String test =
"DomainName=xyz.zzz.com
&ModifiedOn=03%2f17%2f2015
&VD1=MTMwMDE3MDQ%3d
&VD2=B67E48F6969E99A0BC2BEE0E240D2B5C
&SiteLanguage=English"
Here value of VD1=MTMwMDE3MDQ%3d and VD2=B67E48F6969E99A0BC2BEE0E240D2B5C. But these are the dynamic values. Here VD1 and VD2 are seperated by '&'.
Try regex like this :
public static void main(String[] args) throws Exception {
String test = "DomainName=xyz.zzz.com&ModifiedOn=03%2f17%2f2015&VD1=MTMwMDE3MDQ%3d&VD2=B67E48F6969E99A0BC2BEE0E240D2B5C&SiteLanguage=English";
Pattern p = Pattern.compile("VD1=(.*)&VD2=(.*)&");
Matcher m = p.matcher(test);
while(m.find()){
System.out.println(m.group(1));
System.out.println(m.group(2));
}
}
O/P :
MTMwMDE3MDQ%3d
B67E48F6969E99A0BC2BEE0E240D2B5C
You can use regular expressions or use the String index() and split() methods.
A regular expression that matches and captures the VD1 value is
/VD1=([^&]*)/
If you're sure that theres always a "&" behind the values of VD1 and VD2, this kind of splitting will do:
String test = "DomainName=xyz.zzz.com&ModifiedOn=03%2f17%2f2015&VD1=MTMwMDE3MDQ%3d&VD2=B67E48F6969E99A0BC2BEE0E240D2B5C&SiteLanguage=English";
String vd1 = test.substring(test.indexOf("VD1=")+4, test.indexOf("&", test.indexOf("VD1")));
String vd2 = test.substring(test.indexOf("VD2=")+4, test.indexOf("&", test.indexOf("VD2")));
System.out.println("VD1:" + vd1 + "\nVD2:" + vd2);
This is only a demo, for production you'd have to extract the indexes for better performance.
You can use String.split(...) to split a String in pieces. For example, test.split("&") first splits the String in individual tokens (of the form "key=value").
You could do the following to achieve this:
String vd1 = null, vd2 = null;
for (String token : test.split("&")) {
// For each token, we check if it is one of the keys we need:
if (token.startsWith("VD1=")) {
// The number 4 represents the length of the String "vd1="
vd1 = token.substring(4);
} else if (token.startsWith("VD2=") {
vd2 = token.substring(4);
}
}
System.out.println("VD1 = " + vd1);
System.out.println("VD2 = " + vd2);
However, if you want to parse arbitrary keys, consider using a more robust solution (instead of hard-coding the keys in the for-loop).
Also see the documentation for the String class
String test = "DomainName=xyz.zzz.com&Test&ModifiedOn=03%2f17%2f2015&VD1=MTMwMDE3MDQ%3d&VD2=B67E48F6969E99A0BC2BEE0E240D2B5C&SiteLanguage=English";
HashMap<String, String> paramsMap = new HashMap<String, String>();
String[] params = test.split("&");
for (int i=0; i<params.length; i++) {
String[] param = params[i].split("=");
String paramName = URLDecoder.decode(param[0], "UTF-8");
String paramValue = null;
if(param.length > 1)
paramValue = URLDecoder.decode(param[1], "UTF-8");
paramsMap.put(paramName, paramValue);
}
String vd1 = paramsMap.get("VD1");
String vd2 = paramsMap.get("VD2");
I am trying to find environment variables in input and replace them with values.
The pattern of env variable is ${\\.}
Pattern myPattern = Pattern.compile( "(${\\.})" );
String line ="${env1}sojods${env2}${env3}";
How can I replace env1 with 1 and env2 with 2 and env3 with 3, so
that after this I will have a new string 1sojods23?
Strings in Java are immutable, which makes this somewhat tricky if you are talking about an arbitrary number of things you need to find and replace.
Specifically you need to define your replacements in a Map, use a StringBuilder (before Java 9, less performant StringBuffer should have been used) and the appendReplacements() and appendTail() methods from Matcher. The final result will be stored in your StringBuilder (or StringBuffer).
Map<String, String> replacements = new HashMap<String, String>() {{
put("${env1}", "1");
put("${env2}", "2");
put("${env3}", "3");
}};
String line ="${env1}sojods${env2}${env3}";
String rx = "(\\$\\{[^}]+\\})";
StringBuilder sb = new StringBuilder(); //use StringBuffer before Java 9
Pattern p = Pattern.compile(rx);
Matcher m = p.matcher(line);
while (m.find())
{
// Avoids throwing a NullPointerException in the case that you
// Don't have a replacement defined in the map for the match
String repString = replacements.get(m.group(1));
if (repString != null)
m.appendReplacement(sb, repString);
}
m.appendTail(sb);
System.out.println(sb.toString());
Output:
1sojods23
I know this is old, I was myself looking for a, appendReplacement/appendTail example when I found it; However, the OP's question doesn't need those complicated multi-line solutions I saw here.
In this exact case, when the string to replace holds itself the value we want to replace with, then this could be done easily with replaceAll:
String line ="${env1}sojods${env2}${env3}";
System.out.println( line.replaceAll("\\$\\{env([0-9]+)\\}", "$1") );
// Output => 1sojods23
DEMO
When the replacement is random based on some conditions or logic on each match, then you can use appendReplacement/appendTail for example
Hopefully you would find this code useful:
Pattern phone = Pattern.compile("\\$\\{env([0-9]+)\\}");
String line ="${env1}sojods${env2}${env3}";
Matcher action = phone.matcher(line);
StringBuffer sb = new StringBuffer(line.length());
while (action.find()) {
String text = action.group(1);
action.appendReplacement(sb, Matcher.quoteReplacement(text));
}
action.appendTail(sb);
System.out.println(sb.toString());
The output is the expected: 1sojods23.
This gives you 1sojods23:
String s = "${env1}sojods${env2}${env3}";
final Pattern myPattern = Pattern.compile("\\$\\{[^\\}]*\\}");
Matcher m = myPattern.matcher(s);
int i = 0;
while (m.find()) {
s = m.replaceFirst(String.valueOf(++i));
m = myPattern.matcher(s);
}
System.out.println(s);
and this works too:
final String re = "\\$\\{[^\\}]*\\}";
String s = "${env1}sojods${env2}${env3}";
int i = 0;
String t;
while (true) {
t = s.replaceFirst(re, String.valueOf(++i));
if (s.equals(t)) {
break;
} else {
s = t;
}
}
System.out.println(s);
You can use a StringBuffer in combination with the Matcher appendReplacement() method, but if the the pattern does not match, there is no point in creating the StringBuffer.
For example, here is a pattern that matches ${...}. Group 1 is the contents between the braces.
static Pattern rxTemplate = Pattern.compile("\\$\\{([^}\\s]+)\\}");
And here is sample function that uses that pattern.
private static String replaceTemplateString(String text) {
StringBuffer sb = null;
Matcher m = rxTemplate.matcher(text);
while (m.find()) {
String t = m.group(1);
t = t.toUpperCase(); // LOOKUP YOUR REPLACEMENT HERE
if (sb == null) {
sb = new StringBuffer(text.length());
}
m.appendReplacement(sb, t);
}
if (sb == null) {
return text;
} else {
m.appendTail(sb);
return sb.toString();
}
}
Map<String, String> replacements = new HashMap<String, String>() {
{
put("env1", "1");
put("env2", "2");
put("env3", "3");
}
};
String line = "${env1}sojods${env2}${env3}";
String rx = "\\$\\{(.*?)\\}";
StringBuffer sb = new StringBuffer();
Pattern p = Pattern.compile(rx);
Matcher m = p.matcher(line);
while (m.find()) {
// Avoids throwing a NullPointerException in the case that you
// Don't have a replacement defined in the map for the match
String repString = replacements.get(m.group(1));
if (repString != null)
m.appendReplacement(sb, repString);
}
m.appendTail(sb);
System.out.println(sb.toString());
In the above example we can use map with just key and values --keys can be env1 ,env2 ..
Use groups once it is matched ${env1} will be your first group and then you use regex to replace what is in each group.
Pattern p = Pattern.compile("(${\\.})");
Matcher m = p.matcher(line);
while (m.find())
for (int j = 0; j <= m.groupCount(); j++)
//here you do replacement - check on the net how to do it;)