Replace design pattern in query string - java

I have currently some URL like this :
?param=value&offset=19&size=100
Or like that :
?offset=45&size=50&param=lol
And I would like to remove for each case the "offset" and the "value". I'm using the regex method but I don't understand how it's really working... Can you please help me for that?
I also want to get both values of the offset and the size.
Here is my work...
\(?|&)offset=([0-9])[*]&size=([0-9])[*]\
But it doesn't works at all!
Thanks.

Assuming is Javascript & you only want to remove offset param:
str.replace(\offset=[0-9]*&?\,"")
For Java:
str=str.replaceAll("offset=[0-9]*&?","");
//to remove & and ? at the end in some cases
if (str.endsWith("?") || str.endsWith("&"))
str=str.substring(0,str.length()-1);

With out regex .
String queryString ="param=value&offset=19&size=100";
String[] splitters = queryString.split("&");
for (String str : splitters) {
if (str.startsWith("offset")) {
String offset = str.substring(str.indexOf('=') + 1);//like wise size also
System.out.println(offset); //prints 19
}
}

If you need to use a regular expression for this then try this string in java for the regular expression (replace with nothing):
"(?>(?<=\\?)|&)(?>value|offset)=.*?(?>(?=&)|$)"
It will remove any parameter in your URL that has the name 'offset' or 'value'. It will also conserve any required parameter tokens for other parameters in the URL.

Related

Java Regex with Pattern and Matcher

I am using Pattern and Matcher classes from Java ,
I am reading a Template text and I want to replace :
src="scripts/test.js" with src="scripts/test.js?Id=${Id}"
src="Servlet?Template=scripts/test.js" with src="Servlet?Id=${Id}&Template=scripts/test.js"
I'm using the below code to execute case 2. :
//strTemplateText is the Template's text
Pattern p2 = Pattern.compile("(?i)(src\\s*=\\s*[\"'])(.*?\\?)");
Matcher m2 = p2.matcher(strTemplateText);
strTemplateText = m2.replaceAll("$1$2Id=" + CurrentESSession.getAttributeString("Id", "") + "&");
The above code works correctly for case 2. but how can I create a regex to combine both cases 1. and 2. ?
Thank you
You don't need a regular expression. If you change case 2 to
replace Servlet?Template=scripts/test.js with Servlet?Template=scripts/test.js&Id=${Id}
all you need to do is to check whether the source string does contain a ? if not add ?Id=${Id} else add &Id=${Id}.
After all
if (strTemplateText.contains("?") {
strTemplateText += "&Id=${Id}";
}
else {
strTemplateText += "?Id=${Id}";
}
does the job.
Or even shorter
strTemplate += strTemplateText.contains("?") ? "&Id=${Id}" : "?Id=${Id}";
Your actual question doesn't match up so well with your example code. The example code seems to handle a more general case, and it substitutes an actual session Id value instead of a reference to one. The code below takes the example code to be more indicative of what you really want, but the same approach could be adapted to what you asked in the question text (using a simpler regex, even).
With that said, I don't see any way to do this with a single replaceAll() because the replacement text for the two cases is too different. You could nevertheless do it with one regex, in one pass, if you used a different approach:
Pattern p2 = Pattern.compile("(src\\s*=\\s*)(['\"])([^?]*?)(\\?.*?)?\\2",
Pattern.CASE_INSENSITIVE);
Matcher m2 = p2.matcher(strTemplateText);
StringBuffer revisedText = new StringBuffer();
while (m2.find()) {
// Append the whole match except the closing quote
m2.appendReplacement(revisedText, "$1$2$3$4");
// group 4 is the optional query string; null if none was matched
revisedText.append((m2.group(4) == null) ? '?' : '&');
revisedText.append("Id=");
revisedText.append(CurrentESSession.getAttributeString("Id", ""));
// append a copy of the opening quote
revisedText.append(m2.group(2));
}
m2.appendTail(revisedText);
strTemplateText = revisedText.toString();
That relies on BetaRide's observation that query parameter order is not significant, although the same general approach could accommodate a requirement to make Id the first query parameter, as in the question. It also matches the end of the src attribute in the pattern to the correct closing delimiter, which your pattern does not address (though it needs to do to avoid matching text that spans more than one src attribute).
Do note that nothing in the above prevents a duplicate query parameter 'Id' being added; this is consistent with the regex presented in the question. If you want to avoid that with the above approach then in the loop you need to parse the query string (when there is one) to determine whether an 'Id' parameter is already present.
You can do the following:
//strTemplateText is the Template's text
String strTemplateText = "src=\"scripts/test.js\"";
strTemplateText = "src=\"Servlet?Template=scripts/test.js\"";
java.util.regex.Pattern p2 = java.util.regex.Pattern.compile("(src\\s*=\\s*[\"'])(.*?)((?:[\\w\\s\\d.\\-\\#]+\\/?)+)(?:[?]?)(.*?\\=.*)*(['\"])");
java.util.regex.Matcher m2 = p2.matcher(strTemplateText);
System.out.println(m2.matches());
strTemplateText = m2.replaceAll("$1$2$3?Id=" + CurrentESSession.getAttributeString("Id", "") + (m2.group(4)==null? "":"&") + "$4$5");
System.out.println(strTemplateText);
It works on both cases.
If you are using java > 1.6; then, you could use custom-named group-capturing features for making the regex exp. more human-readable and easier to debug.

Java regular expression on matching asterisk only when it is the last character

Anyone can spot any error in this code?
String value = "/files/etc/hosts/*";
if (value.matches("\\*$")) {
System.out.println("MATCHES!");
}
I am trying to do some operation when the last character of a string is an asterisk.
The syntax looks correct to me, I tested it on http://regexpal.com/
Thanks in advance!
Why not just use:
if (value.endsWith("*")) {
String.matches() only returns true if the regex matches the entire CharSequence.
Try either this:
value.matches(".*?\\*$")
Or use a Pattern object.
EDIT: Per comment request.
Pattern glob = Pattern.compile("\\*$");
if (glob.matcher(value).find()) {
System.out.println("MATCHES!");
}
You need to match everything in the String when using String#matches:
if (value.matches(".*\\*$")) {

cannot parse String with Java Regex

I have a string formatted as below:
source1.type1.8371-(12345)->source2.type3.3281-(38270)->source4.type2.903..
It's a path, the number in () is the weight for the edge, I tried to split it using java Pattern as following:
[a-zA-Z.0-9]+-{1}({1}\\d+){1}
[a-zA-Z_]+.[a-zA-Z_]+.(\\d)+-(\\d+)
[a-zA-Z.0-9]+-{1}({1}\\d+){1}-{1}>{1}
hopefully it split the string into fields like
source1.type1.8371-(12345)
source2.type3.3281-(38270)
..
but none of them work, it always return the whole string as the field.
It looks like you just want String.split("->") (javadoc). This splits on the symbol -> and returns an array containing the parts between ->.
String str = "source1.type1.8371-(12345)->source2.type3.3281-(38270)->source4.type2.903..";
for(String s : str.split("->")){
System.out.println(s);
}
Output
source1.type1.8371-(12345)
source2.type3.3281-(38270)
source4.type2.903..
It seems to me like you want to split at the ->'s. So you could use something like str.split("->") If you were more specific about why you need this maybe we could understand why you were trying to use those complicated regexes

How to trim characters from the beginning of a string. Android

I am writing an Android app and need some help.
I have a string that contains a URL. Sometimes I get extra text before the url and need to trim that off.
I get this "Some cool sitehttp://somecoolsite.com"
And want this "http://somecoolsite.com"
First, I need to detect if the string does not start with http:// and then if not, I need to trim everything in front of http://
Is there an easy way to do this?
I can do the first part.
if (url.startsWith("http://") == false) {
url.replace("", replacement)
}
Any help?
To check if the string starts with http:// you do
if (inputUrl.startsWith("http://")) {
...
}
To trim off the prefix up until the first occurrence of http:// you do
int index = inputUrl.indexOf("http://");
if (index != -1)
inputUrl = inputUrl.substring(index);
The API documentation for the String class should provide you with all the information you need here.
Use this:
if(inputURL.contains("http://")
inputURL = inputURL.substring(inputURL.indexOf("http://"));
Another option would be:
inputUrl = inputUrl.replaceAll(".*http://","http://");
it should work under all conditions (but I assume the regular expression is a bit less efficient).
Please note that provided answers assume that the string will be in lower case (no "HTTP" or "Http") and that no strings contain https://

Java regular expression for extracting the data between tags

I am trying to a regular expression which extracs the data from a string like
<B Att="text">Test</B><C>Test1</C>
The extracted output needs to be Test and Test1. This is what I have done till now:
public class HelloWorld {
public static void main(String[] args)
{
String s = "<B>Test</B>";
String reg = "<.*?>(.*)<\\/.*?>";
Pattern p = Pattern.compile(reg);
Matcher m = p.matcher(s);
while(m.find())
{
String s1 = m.group();
System.out.println(s1);
}
}
}
But this is producing the result <B>Test</B>. Can anybody point out what I am doing wrong?
Three problems:
Your test string is incorrect.
You need a non-greedy modifier in the group.
You need to specify which group you want (group 1).
Try this:
String s = "<B Att=\"text\">Test</B><C>Test1</C>"; // <-- Fix 1
String reg = "<.*?>(.*?)</.*?>"; // <-- Fix 2
// ...
String s1 = m.group(1); // <-- Fix 3
You also don't need to escape a forward slash, so I removed that.
See it running on ideone.
(Also, don't use regular expressions to parse HTML - use an HTML parser.)
If u are using eclipse there is nice plugin that will help you check your regular expression without writing any class to check it.
Here is link:
http://regex-util.sourceforge.net/update/
You will need to show view by choosing Window -> Show View -> Other, and than Regex Util
I hope it will help you fighting with regular expressions
It almost looks like you're trying to use regex on XML and/or HTML. I'd suggest not using regex and instead creating a parser or lexer to handle this type of arrangement.
I think the bestway to handle and get value of XML nodes is just treating it as an XML.
If you really want to stick to regex try:
<B[^>]*>(.+?)</B\s*>
understanding that you will get always the value of B tag.
Or if you want the value of any tag you will be using something like:
<.*?>(.*?)</.*?>

Categories

Resources