how to match by regex "to" in url? [duplicate] - java

This question already has an answer here:
Extract parameters and their values from query string in Java
(1 answer)
Closed 7 years ago.
I have this url
http://host.com/routingRequest?returnJSON=true&timeout=60000&to=s%3A73746647+d%3Afalse+f%3A-1.0+x%3A-74.454383+y%3A40.843021+r%3A-1.0+cd%3A-1.0+fn%3A-1+tn%3A-1+bd%3Atrue+st%3ACampus%7EDr&returnGeometries=true&nPaths=1&returnClientIds=true&returnInstructions=true
&hour=12+00&from=s%3A-1+d%3Afalse+f%3A-1.0+x%3A-74.241765+y%3A40.830182+r%3A-1.0+cd%3A-1.0+fn%3A56481485+tn%3A26459042+bd%3Afalse+st%3AClaremont%7EAve&sameResultType=true&type=HISTORIC_TIME
and i try to fetch
to = -74.454383, 40.843021
from = -74.241765, 40.830182
hour = 12+00
with this code:
String patternString = "(x%3A) (.+?) (y%3A) (.+?) (r%3A)";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(freshResponse.regression_requestUrl);
H4 h4 = new H4().appendText("Response ID: " + id);
Ul ul = new Ul();
Li li1 = new Li();
Li li2 = new Li();
if (matcher.find()) {
li1.appendText("From: " + matcher.group(1) + ", " + matcher.group(2));
}
if (matcher.find()) {
li2.appendText("To: " + matcher.group(1) + ", " + matcher.group(2));
}
patternString = "(&hour=) (.+?) (&from=)";
pattern = Pattern.compile(patternString);
matcher = pattern.matcher(freshResponse.regression_requestUrl);
Li li3 = new Li();
if (matcher.find()) {
li3.appendText("At: " + matcher.group(1));
}
but i get no matches. what am i missing?
could I have done this without regex more easily?

Map params = new HashMap();
String url = "http://host.com/routingRequest?returnJSON=true&timeout=60000&to=s%3A73746647+d%3Afalse+f%3A-1.0+x%3A-74.454383+y%3A40.843021+r%3A-1.0+cd%3A-1.0+fn%3A-1+tn%3A-1+bd%3Atrue+st%3ACampus%7EDr&returnGeometries=true&nPaths=1&returnClientIds=true&returnInstructions=true
&hour=12+00&from=s%3A-1+d%3Afalse+f%3A-1.0+x%3A-74.241765+y%3A40.830182+r%3A-1.0+cd%3A-1.0+fn%3A56481485+tn%3A26459042+bd%3Afalse+st%3AClaremont%7EAve&sameResultType=true&type=HISTORIC_TIME";
List<NameValuePair> params = URLEncodedUtils.parse(new URI(url), "UTF-8");
for (NameValuePair param : params) {
map.put(param.getName(),param.getValue());
}
You need to use apache httpclient to get the NameValuePair class.

Related

how to fill an object based on a query param string?

I have strings like that:
//RULE countryname=Brazil&useryear<=2017&usermonth<=01&userdayofmonth<=15 200
I want to fill an object I created like this:
public class Rule {
public List<String> countries;
public LocalDateTime fromTime;
public LocalDateTime toTime;
I used regex, but I wondered if there is a more elegant way to do so?
#Test
public void testRegex() throws Exception {
Pattern pattern = Pattern.compile(".*?flag\\((\\d+)\\)=true(.*)");
Matcher matcher = pattern.matcher("bbbbbbflag(27)=true 300");
while (matcher.find()) {
System.out.println("group 1: " + matcher.group(1));
}
pattern = Pattern.compile("(.*?)countryname=([\\w-]+)(.*)");
matcher = pattern.matcher("countryname=brazil ");
while (matcher.find()) {
System.out.println("group 2: " + matcher.group(2));
}
pattern = Pattern.compile(".*?countryname=(.*+)&.*]");
matcher = pattern.matcher("countryname=brazil&bllllll");
while (matcher.find()) {
System.out.println("group 1: " + matcher.group(1));
}
pattern = Pattern.compile(".*?useryear<=(\\d+)&usermonth<=(\\d+)&userdayofmonth<=(\\d+)(.*)");
matcher = pattern.matcher("useryear<=2017&usermonth<=01&userdayofmonth<=15");
while (matcher.find()) {
System.out.println("group 1: " + matcher.group(1));
System.out.println("group 2: " + matcher.group(2));
System.out.println("group 3: " + matcher.group(3));
}
}
You could combine your patterns with | and then look for all the matches:
String s = "//RULE countryname=Brazil&useryear<=2017&usermonth<=01&userdayofmonth<=15 200\n";
Pattern p = Pattern.compile("((countryname)=([\\w-]+)|(useryear)<=(\\d+)|(usermonth)<=(\\d+)|(userdayofmonth)<=(\\d+))");
Matcher m = p.matcher(s);
while(m.find()){
String type = "";
String value = "";
boolean first = true;
for(int i = 2; i<=m.groupCount(); i++){
String group = m.group(i);
if(first && group != null){
type = group;
first = false;
}else if(group != null){
value = group;
break;
}
}
System.out.println("Type: " + type + " Value: " + value);
}
Outputs:
Type: countryname Value: Brazil
Type: useryear Value: 2017
Type: usermonth Value: 01
Type: userdayofmonth Value: 15
You can do it without a regex. Since your string is similar to an http query with parameters, we can parse it in a similar manner to an http query. Please try if this example can help you.
package gnu;
import java.util.*;
import java.util.stream.Collectors;
import java.util.AbstractMap.SimpleImmutableEntry;
import static java.util.stream.Collectors.toList;
public class Main {
public static void main(String[] strg) {
String str = "//RULE countryname=Brazil&useryear<=2017&usermonth<=01&userdayofmonth<=15 200";
str = str.substring(str.indexOf(" ")+1, str.lastIndexOf(" "));
try {
ParseParams parse = new ParseParams();
Map<String, List<String>> map = parse.parseParams(str);
map.entrySet().forEach(entry -> {
System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
});
} catch (Throwable t) {
t.printStackTrace();
}
}
}
class ParseParams {
Map<String, List<String>> parseParams(String url) {
return Arrays.stream(url.split("&"))
.map(this::splitQueryParameter)
.collect(Collectors.groupingBy(SimpleImmutableEntry::getKey, LinkedHashMap::new, Collectors.mapping(Map.Entry::getValue, toList())));
}
private SimpleImmutableEntry<String, String> splitQueryParameter(String it) {
final int idx = it.indexOf("=");
String key = idx > 0 ? it.substring(0, idx) : it;
String value = idx > 0 && it.length() > idx + 1 ? it.substring(idx + 1) : null;
if (key.contains("<")) {
key = key.replace("<", "");
}
return new SimpleImmutableEntry<>(key, value);
}
}
Output
Key : countryname Value : [Brazil]
Key : useryear Value : [2017]
Key : usermonth Value : [01]
Key : userdayofmonth Value : [15]
Online demo.

examples on how to parse string in java

I have the following string that I need to parse/extract the '20000' out of it.
"where f_id = '20000' and (flag is true or flag is null)"
Any sugguestions on best way to do this?
Here's more code to help understand:
List<ReportDto> reportDtoList = new ArrayList<ReportDto>();
for (Report report : reportList) {
List<ReportDetailsDto> ReportDetailsDtoList = new ArrayList<ReportDetailsDto>();
ReportDto reportDto = new ReportDto();
reportDto.setReportId(report.getReportId());
reportDto.setReportName(report.getName());
Pattern p = Pattern.compile("=\\s'[0-9]+'");
String whereClause = report.getWhereClause();
Matcher m = p.matcher(whereClause);
Confused of what to do after this?
You can use this regex to extract a single nonegative integer from your String
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher(text);
if (m.find()) {
System.out.println(m.group());
}
Or if you want to preserve the single quotes :
Pattern p = Pattern.compile("['0-9]+");
This will extract a pattern that includes '=' and a single space after that. It will print a String containing the number without '=' or the space. So if this matches you know there is a number after a '='
Pattern p = Pattern.compile("=\\s'[0-9]+");
Matcher m = p.matcher(text);
if (m.find()) {
System.out.println(m.group().substring(3));
}
EDIT
based on the code you added this is how it would look like
List<ReportDto> reportDtoList = new ArrayList<ReportDto>();
Pattern p = Pattern.compile("=\\s'[0-9]+");
for (Report report : reportList) {
List<ReportDetailsDto> ReportDetailsDtoList = new ArrayList<ReportDetailsDto>();
ReportDto reportDto = new ReportDto();
reportDto.setReportId(report.getReportId());
reportDto.setReportName(report.getName());
String whereClause = report.getWhereClause();
Matcher m = p.matcher(whereClause);
if (m.find()) {
String foundThis = m.group().substring(3);
// do something with foundThis
} else {
// didn't find a number or =
}
}
Try this:
Pattern p = Pattern.compile("-?\\d+");
String s = "your string here";
Matcher m = p.matcher(s);
List<String> extracted = new ArrayList<String>();
while (m.find()) {
extracted.add(m.group());
}
for floats and negatives
Pattern p = Pattern.compile("(-?\\d+)(\\.\\d+)?");
String s = "where f_id = '20000' 3.2 and (flag is true or flag is null)";
Matcher m = p.matcher(s);
List<String> extracted = new ArrayList<String>();
while (m.find()) {
extracted.add(m.group());
}
for (String g : extracted)
System.out.println(g);
prints out
20000
3.2

While(matcher.find()) - Error - Doesn't Work

I need a sort help
I don't know why it's jump in the while by matcher.find() when i'm have the string "3*3"
code:
public void delSin_Cos_Tan()
{
o = new ArrayList<>();
String aDate = "3*3";
Pattern datePattern = Pattern.compile("((sin|cos|tan|sinh|cosh|tanh|asin|acos|atan)\\((.+)\\))");
//Operat.Sin_Cos_Tan.Patter = ((sin|cos|tan|sinh|cosh|tanh|asin|acos|atan)\((.+)\))
Matcher matcher = datePattern.matcher(aDate);
Log.d(TAG,"Sin Startz");
Log.d(TAG,"Sin " + Aufgabe);
while (matcher.find());
{
Log.e(TAG,matcher.group(1)); // there is the Error, but withe the String "3*3" an i don't konw why it is jump inside the while
String Gesammt = matcher.group(1);
String TYP = matcher.group(2);
String Inklammer = matcher.group(3);
Log.d(TAG, String.valueOf("------------------------"));
Log.d(TAG, Gesammt);
Log.d(TAG, Inklammer);
Log.d(TAG, TYP);
Log.d(TAG, String.valueOf("------------------------"));
}
}
My completely Code: http://pastebin.com/jWN1ghfz
you got a ;after your while loop.
This is why your complete block will always get executed!
while (matcher.find()); should be while (matcher.find()) (whithout ;)
It's because
while (matcher.find());
{
//...
}
is the same as
while (matcher.find()){
;
}
{
//...
}

Regular expression for month pattern date

My task is to find the dates from resume(txt file) and calculate the duration between them
I have crated the regular expression for the duration (date) pattern like
Jan 2012 - present or Jan 2012 - Jan 2013 or 1/2013 - 2/2014 or 01/2012 - 02/2014
here are my regular expressions
private String monthPattern = "((0[1-9]|1[012]|[1-9])|(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sept|Sep|Oct|Nov|Dec)[a-z]*)"; // 3 groups
private String monthAndYearSeperator="\\s*(\\s*|,|;|~|--|-|.|\\/)\\s*"; // 1 group
private String twoOrFourDigitYearPattern="(19[0-9]{2}|[2-9][0-9]{3}|[0-9]{2})\\s*"; // 1 group
private String presentPattern = "(Current|Present|Now|Currently|Presently|Till Date|Todate|Today)";
private String twoDatesSeperator = "\\s*(\\s*|-|~|--|,|to|til|till|until)\\s*"; // 1 group
private String twoOrFourDigitOrPresentYearPattern = presentPattern + "|" + twoOrFourDigitYearPattern; // 2 groups
private String secondIdenticalMonthPattern="(([1-9]|0[1-9]|1[012])|(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sept|Sep|Oct|Nov|Dec|January|February|March|April|May|June|July|August|September|October|November|December))"; // 3 groups
And using the above patterns i have created one pattern for duration
private String dateToDateCompletePatternOne=
monthPattern + monthAndYearSeperator +
twoOrFourDigitYearPattern +
twoDatesSeperator + "((" + secondIdenticalMonthPattern +
monthAndYearSeperator +
twoOrFourDigitYearPattern +")|" +
presentPattern +")"
;
Now my problem is when my Resume file contains the pattern like 2013 - Jan 2014 then my regex is matching to this kind of date also but actually it should not match
please help me with this i am struggling since two weeks
please find the code below
import java.io.IOException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.concurrent.CountDownLatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.w3c.dom.css.Counter;
public class DatePattens {
//private ArrayList<MatchedDateObject> arryLstOfDates = new ArrayList<MatchedDateObject>();
private ArrayList<String> matchedString = new ArrayList<String>();
private HashMap<String,Integer> map ;
private String monthPattern = "((0[1-9]|1[012]|[1-9])|(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sept|Sep|Oct|Nov|Dec)[a-z]*)"; // 3 groups
private String monthAndYearSeperator="\\s*(\\s*|,|;|~|--|-|.|\\/)\\s*"; // 1 group
private String twoOrFourDigitYearPattern="(19[0-9]{2}|[2-9][0-9]{3}|[0-9]{2})\\s*"; // 1 group
private String presentPattern = "(Current|Present|Now|Currently|Presently|Till Date|Todate|Today)";
private String twoDatesSeperator = "\\s*(\\s*|-|~|--|,|to|til|till|until)\\s*"; // 1 group
private String twoOrFourDigitOrPresentYearPattern = presentPattern + "|" + twoOrFourDigitYearPattern; // 2 groups
private String secondIdenticalMonthPattern="(([1-9]|0[1-9]|1[012])|(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sept|Sep|Oct|Nov|Dec|January|February|March|April|May|June|July|August|September|October|November|December))"; // 3 groups
private String dateToDateCompletePatternOne=
monthPattern + monthAndYearSeperator + twoOrFourDigitYearPattern + twoDatesSeperator +
"((" + secondIdenticalMonthPattern +
monthAndYearSeperator +
twoOrFourDigitYearPattern +")|" +
presentPattern +")"
;
private Pattern patternAry = null;
private Matcher matcher = null;
public DatePattens() {
map = new HashMap<String,Integer>();
patternAry = Pattern.compile(dateToDateCompletePatternOne, Pattern.CASE_INSENSITIVE);
matcher = patternAry.matcher("");
}
//
// extract the two dates to look for duration afterwards
// 1. check if the a year pattern exists
// 1.1 if not skip to else at the end and return false
// 2. if yes get the rest of the line past year 1
// 3. check for year 2 or CURRENT/Present/...
public boolean matchTwoYearPattern(String inputLine){
String fname="matchTwoYearPattern";
Pattern firstYearPattern = Pattern
.compile(twoOrFourDigitYearPattern,Pattern.CASE_INSENSITIVE);
Matcher matcher1 = firstYearPattern.matcher("");
Pattern secondPattern = Pattern.compile(twoOrFourDigitOrPresentYearPattern,
Pattern.CASE_INSENSITIVE);
Matcher matcher2 = secondPattern.matcher("");
//long startTime = System.currentTimeMillis();
matcher1.reset(inputLine);
if (matcher1.find()) { // 1
String remaingString = inputLine.substring(matcher1.end(),
inputLine.length()); // 2
matcher2.reset(remaingString);
if (matcher2.find()) { // 3
return true;
}
}
return false; // 1.1 and end
}
public String matchAllDatePatterns(String line, int lineNum){
String fname = "matchAllPatterns:: ";
if (matchTwoYearPattern(line) == false) { // check if two years (or year and CURRENT/today...) present, if not return false
return("false:" + line);
}
else {
}
String matched = "";
int i = 0;
matcher.reset(line);
if (matcher.find()) {
System.out.println(fname + "line: " +line);
System.out.println("group count "+matcher.groupCount());
System.out.println("group1 " +matcher.group(1));
System.out.println("group2 " +matcher.group(2));
System.out.println("group3 " +matcher.group(3));
System.out.println("group4 " +matcher.group(4));
System.out.println("group5 " +matcher.group(5));
System.out.println("group6 " +matcher.group(6));
System.out.println("group7 " +matcher.group(7));
System.out.println("group8 " +matcher.group(8));
System.out.println("group9 " +matcher.group(9));
System.out.println("group10 " +matcher.group(10));
System.out.println("group11 " +matcher.group(11));
System.out.println("group12 " +matcher.group(12));
System.out.println("group13 " +matcher.group(13));
System.out.println("group14 " + matcher.group(14));
}
return matched;
}
public static void main(String args[]){
DatePattens dp= new DatePattens();
String fileName = "Resume.txt";
try {
ReadFile file = new ReadFile(fileName);
String[] aryLines = file.openFile();
int i=0;
long startTime =System.currentTimeMillis();
for(int count=0;count<1;count++){
for (String input : aryLines) {
String output = dp.matchAllDatePatterns(input, i);
i++;
}
}
long endTime =System.currentTimeMillis();
System.out.println("Time required for this operation :" + ((endTime-startTime)*0.001));
} catch (IOException e) {
System.out.println(e);
}
}
}

Java Regex And XML

I've been working on a weekend project, a simple, lightweight XML parser, just for fun, to learn more about Regexes. I've been able to get data in atributes and elements, but am having a hard time separating tags. This is what I have:
CharSequence inputStr = "<a>test</a>abc<b1>test2</b1>abc1";
String patternStr = openTag+"(.*?)"+closeTag;
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(inputStr);
StringBuffer buf = new StringBuffer();
boolean found = false;
while ((found = matcher.find())) {
String replaceStr = matcher.group();
matcher.appendReplacement(buf, "found tag (" + replaceStr + ")");
}
matcher.appendTail(buf);
String result = buf.toString();
System.out.println(result);
Output: found tag (<a>test</a>abc<b1>test2</b1>)abc1
I need to to end the 'found tag' at each tag, not the whole group. Any way I can have it do that? Thanks.
You can try with something as follows to get it working as you require;
int count = matcher.groupCount();
for(int i=0;i<count;i++)
{
String replaceStr = matcher.group(i);
matcher.appendReplacement(buf, "found tag (" + replaceStr + ")");
}

Categories