I am trying to parse out all the toll information from a string that I have. I tested this in eclipse and it works fine but when I implement it in the android IDE and run the code the debugger just stops on the declaration of the pattern i pointed out below. So the program does not crash, there is no stack trace or exception thrown. The other patterns work no problem but the toll pattern just does something really weird.
g="routes:[{routeName:Dulles Toll Rd W; SR-28 S,routeDurationInMinutes:18,routeLengthKM:21.474,routeLengthMiles:13.343320854,toll:true},{routeName:Frying Pan Rd; SR-28 S,routeDurationInMinutes:18,routeLengthKM:19.437,routeLengthMiles:12.077588127,toll:false}],startPoint:12801 Worldgate Drive, Herndon, VA 20170,endPoint:14069 Lotus Ln, Centreville, VA,startLatitude:38.95459763380265,startLongitude:-77.38901112241822,endLatitude:38.954550193428965,endLongitude:-77.38874605682294";
ArrayList parse = new ArrayList();
ArrayList route = new ArrayList();
ArrayList time = new ArrayList();
ArrayList toll= new ArrayList();
final Pattern p = Pattern.compile("routeName?.+?routeLengthKM");
Matcher m = p.matcher(g);
Pattern p2 = Pattern.compile("routeName?.+?routeDurationInMinutes");
Pattern p3 = Pattern.compile("routeDurationInMinutes?.+?routeLengthKM");
Pattern ptoll = Pattern.compile("toll?.+?}"); //<-- dies here
Matcher m3 = p3.matcher(g);
Matcher mtoll = ptoll.matcher(g);
while (m.find()) {
parse.add(m.group());
}
while (m3.find()) {
time.add(m3.group());
}
while (mtoll.find()) {
toll.add(mtoll.group());
}
You need to fix your regular expression. I'm not sure why, but for some reason it doesn't like "toll?.+?}". You need to change that line to this:
Pattern ptoll = Pattern.compile("toll?.+?\\}");
The change being \\ which will escape the } and let Pattern know that it's a literal }.
Related
What I'm trying to do:
if a String is
String a = "Love is rare"; Or
String a = "l o v e is rare"; Or
String a = "LO VE is rare";
Then,
I want the word "love" to be replaced by "hate" ignoring the space and case
My code:
a=a.toLowerCase().replace("love","hate").replace("\\s+","");
But the problem is that it removes all the spaces and change all the words to lower case. I just want to check if there is a word love by ignoring all the spaces and cases and if the word is there then replace it with some other word.
Please help!
Thank you.
Try it like this using an optional whitespace ? and the case insensitive flag. If you want to match zero or more whitespaces, you could use a whitespace and *
l ?o ?v ?e
String regex = "l ?o ?v ?e";
String[] lines = {"Love is rare", "l o v e is rare", "LO VE is rare"};
String subst = "hate";
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
for (String line: lines) {
Matcher matcher = pattern.matcher(line);
String result = matcher.replaceAll(subst);
System.out.println(result);
}
That would give you:
hate is rare
hate is rare
hate is rare
Demo Java
Thanks for suggesting the term regex, Studied thoroughly and come up with this one line function which will replace "love" by "hate" ignoring the spaces and cases:
String a = "Lo ve is rare.";
Code:
a = a.replaceAll("(?i)l(\\s*)o(\\s*)v(\\s*)e","hate");
TextView.setText(a);
This would give:
hate is rare.
I'm trying to use a regex to match some text in a string.
The problem is it is always -1 even if I have a match.
holder.textViewPublisher.setText(post.getPublisher());
Pattern tagMatcher = Pattern.compile("[#]+[A-Za-z0-9-_]+\\b");
int start = post.getPublisher().indexOf(tagMatcher.toString());
int end = start + tagMatcher.toString().length();
any ideas why start is always -1?
Because you're using it wrong. String.indexOf() doesn't use regexps, it just looks for substring ("[#]+[A-Za-z0-9-_]+\\b" in your case).
Code should be something like this:
Pattern tagMatcher = Pattern.compile("[#]+[A-Za-z0-9-_]+\\b");
Matcher m = tagMatcher.matcher(post.getPublisher());
if (m.find()) {
// matches
int start = m.start();
int end = m.end();
}
find() can be called several times to find all of the occurences of pattern. Look in the Pattern and Matcher docs for details.
It's returning -1 because you're looking for the index of the regex pattern itself as a string instead of looking for a match. You need to use the Matcher object to find an instance of a match.
I'm trying to use regex in an Android application to read a substring. I'm using Pattern and Matcher, but I can't figure out how to do it.
My input string is: javascript:submitForm(document.voip_call_log,30,0,'xxxxx','',0,'');
where xxxxx is a variable number of digits.
How can I read 'xxxxx' using Pattern and Matcher?
I'm not an expert in RegEx, but this one should work for you:
String input = "javascript:submitForm(document.voip_call_log,30,0,'5555','',0,'');";
Pattern pattern = Pattern.compile(",'(\\d*)',");
Matcher matcher = pattern.matcher(input);
matcher.find();
String out = matcher.group(1);
System.out.println(out);
Proof http://ideone.com/WI6VB1
If you will have always that format, it might be easier to use the split(",") method and access the value you like.
Alternatively, you could try something like so:
String str = ...;
Pattern p = Pattern.compile("(\\d{3,})");
Matcher m = p.matcher(str);
while(m.find())
{
System.out.println(m.group(1));
}
Try this one:
String s = "javascript:submitForm(document.voip_call_log,30,0,'1999','',0,'');";
Pattern pattern = Pattern.compile("javascript:submitForm\\([^,]+,\\d*,\\d*,'(\\d+)','\\d*'");
Matcher m = pattern.matcher(s);
if(m.find( )) {
System.out.println(m.group(1));
}
This is following the pattern of your input string from the question description. You can find the explanation of your regex from this link. Just input your regex with single slash \ instead of double \\
i have some problems extracting strings
i am making a multiple choice with 4 choices (e.g. as buttons), with the choices by referencing to the filename. The file (i.e. the question) is a png and the filename is Number-Q01AZ7BZ8CZ9DZ10ANZ8.png. These png are put under assets folder.
Set<String> regions = regionsMap.keySet(); // get Set of regions
// loop through each region
for (String region : regions)
{
if (regionsMap.get(region)) // if region is enabled
{
// get a list of all flag image files in this region
String[] paths = assets.list(region);
for (String path : paths)
fileNameList.add(path.replace(".png", ""));
} // end if
} // end for
String fileName = fileNameList.get(randomIndex);
if (!quizCountriesList.contains(fileName))
{
quizCountriesList.add(fileName); // add the file to the list
String nextImageName = quizCountriesList.remove(0);
correctAnswer = nextImageName; // update the correct answer
int AZ = correctAnswer.indexOf("AZ");
int BZ = correctAnswer.indexOf("BZ");
int CZ = correctAnswer.indexOf("CZ");
int DZ = correctAnswer.indexOf("DZ");
int ANZ = correctAnswer.indexOf("ANZ");
String choiceA = null;
String choiceB = null;
String choiceC = null;
String choiceD = null;
choiceA = correctAnswer.substring( (AZ+2), (BZ) );
choiceB = correctAnswer.substring( (BZ+2), (CZ) );
choiceC = correctAnswer.substring( (CZ+2), (DZ) );
choiceD = correctAnswer.substring( (DZ+2), (ANZ) );
The logcat is as follows:
11-09 21:14:08.495: E/AndroidRuntime(25905): FATAL EXCEPTION: main
11-09 21:14:08.495: E/AndroidRuntime(25905): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.trial.quizgame/com.trial.quizgame.QuizGame}: java.lang.StringIndexOutOfBoundsException: length=15; regionStart=1; regionLength=-2
11-09 21:14:08.495: E/AndroidRuntime(25905): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
I have tried to set the buttons as .setText(correctAnswer) and it will correctly show as Number-Q01AZ7BZ8CZ9DZ10ANZ8, so the top part of getting the String for "correctAnswer" should be ok. The problem left at extracting strings, yet BZ must be at a position behind AZ, so as CZ behind BZ, etc:
From the logcat the regionLength is -2? How could I handle this?
I would like it to be for Q01, choice A=7, B=8, C=9, D=10 and ANZ=8
thanks in advance for your advice!
Your assumption on the strings value is wrong. This code, if AZ, BZ, CZ, DZ, ANZ is present, should run with no error.
Either run debugger as advised in comments, or use android logcat to provide some debugging context. android.utils.Log.d("APP", String.format("AZ=%d", AZ));
How you store your data is not a big deal. You can tune it for days... You could create xml files that contain the name of the image, and the four possible answers... You can use the underscore approach, you can stay with your current one. Til it is only used by you, it doesn't really matter. You should just keep it simple. More complex => more chance for bugs...
So I'd advise reading about debugging and logging instead of refining the way you store the information... Storing it in the filename, that's a smart idea, quick and efficient, an ideal hack...
I am currently using afreechart to plot a graph in my Android app. I am using the TimeSeries graph, that they've exemplified in their sample app. For me, data to be extracted from two databases.Two questions :
1. How to plot this TimeSeries graph using values from my two databases?
2. The whole graph is not as smooth as one would want to. Especially when scrolling or flicking. And hence, it's inconsistent with the app design. Any way I could make it smoother?
If the questions above seems unnecessary or in some way wrong, please point me to a way where I can plot a graph using multiple database values, even if it's not using afreechart. Thanks.
I tried using simple 'for' loops in createDataset(), like :
private static XYDataset createDataset() {
mfirstDbHelper.open();
msecondDbHelper.open();
int firstdb_count = (int) DatabaseUtils.queryNumEntries(mfirstDbHelper.mDb,firstDbAdapter.DATABASE_TABLE);
int seconddb_count = (int) DatabaseUtils.queryNumEntries(msecondDbHelper.mDb,secondDbAdapter.DATABASE_TABLE);
TimeSeriesCollection dataset = new TimeSeriesCollection();
for(int i=1;i<=seconddb_count;i++){
Cursor seconddb = msecondDbHelper.fetchItem(i);
TimeSeries s1 = new TimeSeries(seconddb.getString(
seconddb.getColumnIndexOrThrow(secondDbAdapter.KEY_ITEMNAME)));
for(int j=1;j<=firstdb_count;j++){
Cursor firstdb = mfirstDbHelper.fetchItem(j);
int first_sp_id = Integer.parseInt(firstdb.getString(
firstdb.getColumnIndexOrThrow(firstDbAdapter.KEY_ID)));
if(first_sp_id == i){
int value = Integer.parseInt(firstdb.getString(
firstdb.getColumnIndexOrThrow(firstDbAdapter.KEY_VALUE)));
String date = firstdb.getString(
firstdb.getColumnIndexOrThrow(firstDbAdapter.KEY_DATE));
String dateParts[] = date.split("-");
String day = dateParts[0];
String month = dateParts[1];
String year = dateParts[2];
int d = Integer.parseInt(day);
int m = Integer.parseInt(month);
int y = Integer.parseInt(year);
s1.add(new Day(d,m,y), value);
dataset.addSeries(s1);
}
firstdb.close();
}
seconddb.close();
}
mfirstDbHelper.close();
msecondDbHelper.close();
return dataset;
}
}
I have changed the Month() in sample to Day(), and have made sure there's no error in that area.
Am getting the error:
ERROR/AndroidRuntime(706): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kev/com.kev.MyProject}: java.lang.NullPointerException
Also, obviously, this code redraws the graph "s1" over and over again. I do not know how to overcome this problem, and the error. Am still fairly new to programming, especially Android app development, so any blunders above, feel free to smack me in the head and correct my code.
Oh, one more thing, I can't use startManagingCursor() since it's a DemoView and not Activity. So, don't know if its causing any problems either.
Afreechart TimeSeries sample:
http://code.google.com/p/afreechart/source/browse/#svn%2Ftrunk%2Fafreechart_sample%2Fsrc%2Forg%2Fafree%2Fchart%2Fdemo
Afreechart TimeSeries sample - View:
http://code.google.com/p/afreechart/source/browse/trunk/afreechart_sample/src/org/afree/chart/demo/view/TimeSeriesChartDemo01View.java
Thanks again, for your time. :)