There was some XML parsed text that looked like this:
06:00 Vesti<br>07:15 Something Else<br>09:10 Movie<a href="..."> ... <br>15:45 Something..
and there was a lot of it..
Well, I have done this:
String mim =ses.replaceAll("(?s)\\<.*?\\>", " \n");
there was no other way to show text nicely.
Now, after few showings, and some time, I need that same text separated into alone strings like this:
06:00 Vesti
... or
07:15 Something Else
I've tried something like this, but it does not work:
char[] rast = description.toCharArray();
int brojac = 0;
for(int q=0; q<description.length(); q++){
if(rast[q]=='\\' && rast[q+1]=='n' ) brojac++;
}
String[] niz = new String[brojac];
int bf1=0;
int bf2=0;
int bf3=0;
int oo=0;
for(int q=0; q<description.length(); q++){
if(rast[q]=='\\'&& rast[q+1]=='n'){
bf3=bf1;
bf1=q;
String lol = description.substring(bf3, bf1);
niz[oo]=lol;
oo++;
}
}
I know that in description.substring(bf3,bf1) are not set as they should be but I think that this:
if(rast[q]=='\\' && rast[q+1]=='n)
does not work that way.. is there any other solution?
Note. there is no other way to get that resource. , It must be through this.
Calling Html.fromHtml(String) will properly translate the <br> into \n.
String html = "06:00 Vesti<br>07:15 Something Else<br>09:10 Movie<a href=\"...\"> ... <br>15:45 Something..";
String str = Html.fromHtml(html).toString();
String[] arr = str.split("\n");
Then, just split it on a line basis - no need for regexps (which you shouldn't be using to parse HTML in the first case).
Edit: Turning everything into a bunch of Dates
// Used to find the HH:mm, in case the input is wonky
Pattern p = Pattern.compile("([0-2][0-9]:[0-5][0-9])");
SimpleDateFormat fmt = new SimpleDateFormat("HH:mm");
SortedMap<Date, String> programs = new TreeMap<Date, String>();
for (String row : arr) {
Matcher m = p.matcher(row);
if (m.find()) {
// We found a time in this row
ParsePosition pp = new ParsePosition(m.start(0));
Date when = fmt.parse(row, pp);
String title = row.substring(pp.getIndex()).trim();
programs.put(when, title);
}
}
// Now programs contain the sorted list of programs. Unfortunately, since
// SimpleDateFormat is stupid, they're all placed back in 1970 :-D.
// This would give you an ordered printout of all programs *AFTER* 08:00
Date filter = fmt.parse("08:00");
SortedMap<Date, String> after0800 = programs.tailMap(filter);
// Since this is a SortedMap, after0800.values() will return the program names in order.
// You can also iterate over each entry like so:
for (Map.Entry<Date,String> program : after0800.entrySet()) {
// You can use the SimpleDateFormat to pretty-print the HH:mm again.
System.out.println("When:" + fmt.format(program.getKey()));
System.out.println("Title:" + program.getValue());
}
Use regex:
List<String> results = new ArrayList<String>();
Pattern pattern = Pattern.compile("(\d+:\d+ \w+)<?");
Matcher matcher = pattern.matcher("06:00 Vesti<br>07:15 Something Else<br>09:10 Movie<a href="..."> ... <br>15:45 Something..");
while(matcher.find()) {
results.add(matcher.group(0));
}
results will end up as a list of strings:
results = List[
"06:00 Vesti",
"07:15 Something Else",
"09:10 Movie",
"15:45 Something.."]
See Rexgex Java Tutorial for an idea of how javas regex library works.
Related
In my phonebook on my mobile I have all sorts of contacts like :
+(353) 085 123 45 67
00661234567
0871234567
(045)123456
I'm putting them all into E.164 format which I've largely completed but the question I need resolved is this:
How can I strip all characters (including spaces) except numbers in my string, apart from the first character if it is '+' or a number ?
string phoneNumberofContact;
So for example the cases above would look like :
+3530851234567
00661234567
0871234567
045123456
Update
To handle + only in the first position, you could do:
boolean starsWithPlus = input.charAt(0) == '+';
String sanitized = input.replaceAll("[^0-9]", "");
if (startsWithPlus) {
sanitized = "+" + sanitized;
}
So basically I'm checking to see if it starts with plus, then stripping out everything but digits, and then re-adding the plus if it was there.
Original
Assuming you only want to keep + or digits, a simple regex will work, and String provides the replaceAll() method to make it even easier.
String sanitized = input.replaceAll("[^+0-9]", "");
This method would do the trick
public String cleanPhoneDigits(String phonenum) {
StringBuilder builder = new StringBuilder();
if (phonenum.charAt(0).equals('+') {
builder.append('+');
}
for (int i = 1; i < phonenum.length(); i++) {
char c = phonenum.charAt(i);
if (Character.isDigit(c)) {
builder.append(c);
}
}
return builder.toString();
}
I am creating and android app that randomly generates any category, I would like to get the given random category word. This is the example string
String="The category Animals that starts with a letter J";
or
String="The category Colors that starts with a letter V";
I need to get the word Animals or Colors every random String is generated
A not so advanced solution, but easy to understand:
public void findCategory() {
String string = "The category Colors that starts with a letter V";
String[] split = string.split(" ");
int i;
for (i = 0; i < split.length; i++) {
if ("category".equals(split[i])) {
break;
}
}
System.out.println(split[i + 1]);
}
You may use regex.
Matcher m = Pattern.compile("\\bcategory\\s+(\\S+)").matcher(str);
while(m.find()) {
System.out.println(m.group(1));
}
OR
Matcher m = Pattern.compile("(?<=\\bcategory\\s)\\S+").matcher(str);
while(m.find()) {
System.out.println(m.group());
}
Please use Matcher and Pattern -
String input = "The category Animals that starts with a letter J";
Matcher m1 = Pattern.compile("^The category (.*) that starts with a letter (.*)$").matcher(input);
if(m1.find()) {
String _thirdWord = m1.group(1); // Animals
String _lastWord = m1.group(2); // J
System.out.println("Third word : "+_thirdWord);
System.out.println("Last Word : "+_lastWord);
}
Use this, it might fix your issue
String string = "The category Colors that starts with a letter V";
String[] ar = string.split(" ");
System.out.println(ar[2]);
I am having problems with this NumberFormatException Invalid Long. The log cat is showing that the error is coming from the Long.parseLong part of the method.
public static String getDateTimeStr(String p_time_in_millis) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
Date l_time = new Date(Long.parseLong(p_time_in_millis));
return sdf.format(l_time);
}
Can someone tell me why this code works fine when I fetch and display the data in certain calendars then in other calendars on my device I get this NumberFormatException Invalid Long please?
Edit: Here is the rest of the codeā¦
private void getEvents() {
Uri l_eventUri;
ArrayList<Map<String, String>> allStudents = new ArrayList<Map<String, String>>();
if (Build.VERSION.SDK_INT >= 8) {
l_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
l_eventUri = Uri.parse("content://calendar/events");
}
String[] l_projection = new String[]{"title", "dtstart", "dtend"};
#SuppressWarnings("deprecation")
Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, "calendar_id=" + m_selectedCalendarId, null, "dtstart DESC, dtend DESC");
if (l_managedCursor.moveToFirst()) {
int l_colTitle = l_managedCursor.getColumnIndex(l_projection[0]);
int l_colBegin = l_managedCursor.getColumnIndex(l_projection[1]);
int l_colEnd = l_managedCursor.getColumnIndex(l_projection[2]);
String l_title = String.valueOf(l_colTitle);
String l_begin = Integer.toString(l_colBegin);
String l_end = Integer.toString(l_colEnd);
do {
Map<String, String> map = new HashMap<String, String>();
l_title = l_managedCursor.getString(l_colTitle);
l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));
l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));
map.put("eventTitles", l_title);
map.put("event_begin", l_begin);
map.put("event_end", l_end);
allStudents.add(map);
} while (l_managedCursor.moveToNext());
l_managedCursor.close();
SimpleAdapter adapter = new SimpleAdapter(this, allStudents, R.layout.notice_layout, new String[] { "eventTitles", "event_begin", "event_end" }, new int[] { R.id.tvTitle, R.id.tvBody, R.id.tvTeacherCode});
listViewCalendar.setAdapter(adapter);
}
}
Edit 2:
For some reason the code works fine without this line of code so I've nailed it down to this line of code.
l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));
Why does the l_colEnd get caught up in an NumberFormatExcetion? When the following line of code could be also caught up in the same NumberFormatException because it is enquiring about the same int format?
l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));
Thank you too all who have helped. The other interesting thing also is when I add this
int l_cnt = 0;
do {
++l_cnt;
} while (l_managedCursor.moveToNext() && l_cnt < 100);
to the while clause as shown below at the end of the following code the app works fine with no lines of code throwing a NumberFormatException..
if (l_managedCursor.moveToFirst()) {
int l_cnt = 0;
int l_colTitle = l_managedCursor.getColumnIndex(l_projection[0]);
int l_colBegin = l_managedCursor.getColumnIndex(l_projection[1]);
int l_colEnd = l_managedCursor.getColumnIndex(l_projection[2]);
String l_title = String.valueOf(l_colTitle);
String l_begin = Integer.toString(l_colBegin);
String l_end = Integer.toString(l_colEnd);
do {
Map<String, String> map = new HashMap<String, String>();
l_title = l_managedCursor.getString(l_colTitle);
l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));
l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));
map.put("eventTitles", l_title);
map.put("event_begin", l_begin);
map.put("event_end", l_end);
allStudents.add(map);
++l_cnt;
} while (l_managedCursor.moveToNext() && l_cnt < 100);
Can someone tell me why this code works fine when I fetch and display
the data in certain calendars then in other calendars on my device I
get this NumberFormatException Invalid Long please?
Date l_time = new Date(Long.parseLong(p_time_in_millis));
IMO. This code is "bad" code.
Why? You try to fetch unknown data from unchecked sources
"content://com.android.calendar/events" and "content://calendar/events"
Almost everybody can access calendars and save whatever he like... Sadly there is no rule there for using this! So making a wild guess an app is using this event column to save data in another that your expected format.
Regarding the check l_cnt < 100, where fail stops
It's not failing because the error happens to 101 event or later!
My solution would to check my data, and never trust that other apps will act as I expected or as they should.
So I suggest to change getDateTimeStr method as follows:
public static String getDateTimeStr(String p_time_in_millis) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
long timestamp = 0;
try {
timestamp = Long.parseLong(p_time_in_millis)
} catch(NumberFormatException e) {
Log.w("getDateTimeStr", "Cannot convert '"+p_time_in_millis+"' to long");
e.printStackTrace(); // Prints full error exception
}
Date l_time = new Date(timestamp);
return sdf.format(l_time);
}
Remove the l_cnt < 100 check and leave the code to run checking your logcat! You will now have a better overview of what is happening and also your bad data dates will be 1/1/1970 (due to 0 timestamp) code can be changed responsively in order to handle that dates which does not have the expected format.
Some ideas for handling errors:
Make getDateTimeStr throw an exception to the getEvents() which could catch it and ignore the event with the unexpected data. (Handling logic, ignoring what I cannot understand.)
Recognize the format of the p_time_in_millis in each different case and use different DATE_TIME_FORMAT types regarding the exact format of each event. Okey, that's needs a lot of investigation and still can fail. Also you have to add the case that the format is still unknown so maybe ignore it or use a default value in order not to crash.
Generally, you always try to write a stable app that will not fail if another app saves data in a different format (because it like so or due to its own bug)
I currently have the code below and it successfully returns all the numbers that are present in a string I have.
An example of the string would be say: 1 egg, 2 rashers of bacon, 3 potatoes.
Pattern intsOnly = Pattern.compile("\\d+");
Matcher matcher = intsOnly.matcher(o1.getIngredients());
while (matcher.find()) {
Toast.makeText(this, "" + matcher.group(), Toast.LENGTH_LONG).show();
}
However, I would like to multiply these numbers by say four and then place them back in the original string. How can I achieve this?
Thanks in advance!
I've never tried this, but I think appendReplacement should solve your problem
Doing arithmetic is a little complicated while doing the find()
Pattern intsOnly = Pattern.compile("\\d+");
Matcher matcher = intsOnly.matcher(test);
int start = 0;
int end = 0;
StringBuffer resultString = new StringBuffer();
while (matcher.find()) {
start = matcher.start();
// Copy the string from the previous end to the start of this match
resultString.append(test.substring(end, start));
// Append the desired new value
resultString.append(4 * Integer.parseInt(matcher.group()));
end = matcher.end();
}
// Copy the string from the last match to the end of the string
resultString.append(test.substring(end));
This StringBuffer will hold the result you are expecting.
I want to split a string and get a word finally. My data in database is as follows.
Mohandas Karamchand Gandhi (1869-1948), also known as Mahatma Gandhi, was born in Porbandar in the present day state of Gujarat in India on October 2, 1869.
He was raised in a very conservative family that had affiliations with the ruling family of Kathiawad. He was educated in law at University College, London.
src="/Leaders/gandhi.png"
From the above paragraph I want get the image name "gandhi". I am getting the index of "src=". But now how can I get the image name i.e "gandhi" finally.
My Code:
int index1;
public static String htmldata = "src=";
if(paragraph.contains("src="))
{
index1 = paragraph.indexOf(htmldata);
System.out.println("index1 val"+index1);
}
else
System.out.println("not found");
You can use the StringTokenizer class (from java.util package ):
StringTokenizer tokens = new StringTokenizer(CurrentString, ":");
String first = tokens.nextToken();// this will contain one word
String second = tokens.nextToken();// this will contain rhe other words
// in the case above I assumed the string has always that syntax (foo: bar)
// but you may want to check if there are tokens or not using the hasMoreTokens method
Try this code. Check if it working for you..
public String getString(String input)
{
Pattern pt = Pattern.compile("src=.*/(.*)\\..*");
Matcher mt = pt.matcher(input);
if(mt.find())
{
return mt.group(1);
}
return null;
}
Update:
Change for multiple item -
public ArrayList<String> getString(String input)
{
ArrayList<String> ret = new ArrayList<String>();
Pattern pt = Pattern.compile("src=.*/(.*)\\..*");
Matcher mt = pt.matcher(input);
while(mt.find())
{
ret.add(mt.group(1));
}
return ret;
}
Now you'll get an arraylist with all the name. If there is no name then you'll get an empty arraylist (size 0). Always make a check for size.