string split function is not working as desired - java

I am trying to split date with milliseconds and print in my format, but having index out of bound exception. It is working in case of split("/") but not with split(".").
I don't know why this is happening.
Code is:
public class c {
public static void main(String[] arg)
{
Date date=new Date();
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss.FFF");
System.out.println(formatter.format(date));
String a=formatter.format(date);
String b[]=a.split(" ")[0].split("/");
String x1=(Integer.parseInt(b[2])-2000)+b[1]+b[0];
System.out.println("date part is : "+x1);
String c[]=a.split(" ")[1].split(":");
System.out.println(c[0]);
System.out.println(c[1]);
System.out.println(c[2]);
System.out.println(c[2].trim().split(".")[0]);// exception at this line
System.out.println(c[2].trim().split(".")[1]);
String x2=c[0]+c[1]+c[2].split(".")[0]+c[2].split(".")[1]+"";
System.out.println("time part is : "+x2);
}
}
Log is:
08/10/2013 12:02:18.002
date part is : 131008
12
02
18.002
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:0 at c.main(c.java:22)

java.lang.String.split(String regex) takes a regular expressions as the argument.
A single dot . is the regular expression for 'any character'. So you split you input after every character.
Escape the dot:
split("\\.");

You can use java.util.regex.Pattern.quote(".") to split the string by "."
str.split(java.util.regex.Pattern.quote("."));

try not to split... u can always use this formatter.day | .month | .hour or so on....

Related

Extracting string from filename after removing Date from the string

I have a requirement where depending on the filename I am required to call different methods
filename example are as below
Abc_def_20180719_ghi.txt
Pqr_xy_gh_20180730.txt
Here I want to remove all the characters once I encounter datepattern
So the output should be like:
"Abc_def"
"Pqr_xy_gh"
Please suggest suitable string operations with regex
For filtering all numbers you can use: yourText.replaceAll("[0-9]","") .
But if you want to drop the .txt use: yourTextAfterReplacingAll.split("\\.")
The text you want is in yourTextAfterSplit[0]
You can use following regex to detect required portion of file name
/.+(?=_\d{8})/
For demonstration have a look here. It detects any character except line breaks before an underscore and concurrent 8 digits which is pattern of date.
It may be overthinking it a little to validate that the date at least superficially looks like a good date. This regex could be simplified if you don't care about invalid dates like 10664964.
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DatePrefix {
// no digits before date; year must be between 2000 and 9999
// month from 01 to 12, day from 01 to 31
private static Pattern beforeDate = Pattern.compile(
"([^0-9]+)_[2-9]\\d{3}(?:0[1-9]|1[0-2])(?:0[1-9]|[1-2]\\d|3[01])");
public static void main(String[] args) {
for (String filename : args) {
getPrefixBeforeDate(filename)
.ifPresentOrElse(
prefix -> System.out.format("Found %s%n", prefix),
() -> System.out.format("Bad date: %s%n", filename));
}
}
public static Optional<String> getPrefixBeforeDate(String filename) {
Matcher matcher = beforeDate.matcher(filename);
if (matcher.find()) {
return Optional.of(matcher.group(1));
}
return Optional.empty();
}
}
When called with:
java DatePrefix Pq_xy_20180229.txt Abc_def_ghi_20380323_foo_1200.xml \
Hey_its_20182395.gif Foo_bar.txt
It prints:
Found Pq_xy
Found Abc_def_ghi
Bad date: Hey_its_20182395.gif
Bad date: Foo_bar.txt
The pattern could simply be the following if you don't care whether the date looks at all valid:
private static Pattern beforeDate = Pattern.compile("([^0-9]+)_\\d{8}");
Try this pattern:
[\w\d]+[A-Z-a-z][_]
You can test is online

Java regular expression to parse between dates?

I am struggling to come up with a regular expression to parse some logs that are very unstructured but always have a date that begins with the line that needs to be parsed.
An example is 2015-9-20 05:20:22 lots of log data and then the next date for the next line. So I would basically need to parse everything from the starting date until the next date.
2015-9-20 05:20:22 lots of log data
2015-9-20 05:21:22 lots of new log data
Is it possible to parse this using regular expression?
So I would basically need to parse everything from the starting date until the next date.
If you want to match lines beggining with one date, or beggining with the following day (startDate + 1 day), you can use it in your pattern as literal text.
Using the dates in your example:
^(?:2015-9-20|2015-9-21) .*
Code:
// Instantiate a Date object
Date startDate = new GregorianCalendar(2015, 8, 20).getTime();
// Calculate end date (+1 day)
Calendar endDate = Calendar.getInstance();
endDate.setTime(startDate);
endDate.add(Calendar.DATE, 1); // Add 1 day
// format dates the same way logs use
SimpleDateFormat ft =
new SimpleDateFormat ("y-M-d");
// Create regex
String datesRegex = "^(?:" + ft.format(startDate) + "|" + ft.format(endDate.getTime()) + ") .*";
DEMO
If you want to get all lines from one date to another, and not only those starting with a given date, you should match with the .DOTALL modifier:
^2015-9-20 .*?(?=^2015-9-21 |\z)
Code:
// Create regex
String datesRegex = "^" + ft.format(startDate) + " .*?(?=^" + ft.format(endDate.getTime()) + " |\\z)";
// Compile
Pattern.compile(datesRegex, Pattern.MULTILINE | Pattern.DOTALL);
DEMO
Assuming you're reading the file line-by-line, this should work for you:
^\d{4}-\d{1,2}-\d{2} \d{2}:\d{2}:\d{2} (.*)$
Code example:
String line = "2015-9-20 05:20:22 log data" + System.lineSeparator();
String pattern = "^\\d{4}-\\d{1,2}-\\d{2} \\d{2}:\\d{2}:\\d{2} (.*)$";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("Value after timestamp is: " + m.group(1));
} else {
System.out.println("NO MATCH");
}
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches
{
public static void main( String args[] ){
String s1 = "2015-9-20 05:20:22 lots of log data";
String s2 = "2015-9-20 05:21:22 lots of new log data";
String pattern = "(\\d{4})-(0?\\d|1[0-2])-([012]\\d|3[01]) ([01]?\\d|2[0-4]):([0-5]?\\d):([0-5]?\\d)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(s1); //same for s2
if(m.find())
System.out.println("True");
else
System.out.println("False");
}
}
Output: True

Regex: How to include character of "if" condition

I'm making a date extractor using regex in java. Problem is that date is 20-05-2014 and my program is extracting 0-5-14. In short, how can I get the character on which I'm checking the second character of date?
int count = 0;
String data = "HellowRoldsThisis20-05-2014. farhan_rock#gmail.comHellowRoldsThisis.farhan#gmail.com";
String regexOfDate = "((?<=[0])[1-9]{2})|((?<=[12])[0-9])|((?<=[3])[01])\\.\\-\\_((?<=[0])[1-9])|((?<=[1])[0-2])\\.\\-\\_((?<=[2])[0-9]{4})"; \\THE PROBLEM
String[] extractedDate = new String[1000];
Pattern patternDate = Pattern.compile(regexOfDate);
Matcher matcherDate = patternDate.matcher(data);
while(matcherDate.find()){
System.out.println("Date "+count+"Start: "+matcherDate.start());
System.out.println("Date "+count+"End : "+matcherDate.end());
extractedDate[count] = data.substring(matcherDate.start(), matcherDate.end());
System.out.println("Date Extracted: "+extractedDate[count]);
}
You can try the regular expression:
// (0[1-9]|[12][0-9]|[3][01])[._-](0[1-9]|1[0-2])[._-](2[0-9]{3})
"(0[1-9]|[12][0-9]|[3][01])[._-](0[1-9]|1[0-2])[._-](2[0-9]{3})"
A single regex o match valid dates is awful.
I'd do:
String regexOfDate = "(?<!\\d)\\d{2}[-_.]\\d{2}[-_.]\\d{4}(?!\\d)";
to extract the potential date, then test if it is valid.

How correctly convert this String using substring() Java method?

I have the following problem using the substring() Java function.
I have to do the following operation:
I have a String representing a date having the following form: 2014-12-27 (YEARS-MONTH-DAY).
And I want convert it into a String like this: 20141227 (without the space betwen date component).
So I have implemented the following method that use the substring() method to achieve this task:
private String convertDate(String dataPar) {
String convertedDate = dataPar.substring(0,3) + dataPar.substring(5,6) + dataPar.substring(8,9);
return convertedDate;
}
But it don't work well and return to me wrong conversion. Why? What am I missing?
Use replace method which will replace all ocurrences of '-' for '':
private String convertDate(String dataPar) {
return dataPar.replace('-', '');
}
A simple way would be to replace all the occurrences of -. If the separator could be different then maybe using SimpleDateFormat would be better.
private String convertDate(String dataPar) {
return datapar.replaceAll("-", "");
}
Try replaceAll (This ll replace - with "" means it ll remove -) :
private String convertDate(String dataPar) {
if(dataPar.length() > 0){
return dataPar.replaceAll("-","");
}
return "NOVAL";
}
If the input is only a date, you can use the SimpleDateFormat and use a format like yyMMdd http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
I want you to just change the end indeces of the substring() methods as given below
String convertedDate = dataPar.substring(0,4) + dataPar.substring(5,7) + dataPar.substring(8,10);
I tested, It works Fine as you requested :)
private String convertDate(String dataPar) {
final String year = dataPar.substring(0, 4);
final String month = dataPar.substring(5, 7);
final String day = dataPar.substring(8, 10);
return year + month + day;
}

Java: replacing characters in a String

I have a String that represents a time value and is stored in the following format:
1:31:25
I would like to replace the colons and change the format to:
1h 31m 25s
What function in Java will let me replace the first two colons with 'h ' and 'm ', and the end of the string with 's'.
You could do something like this:
String[] s = myString.split(":");
String.format("%sh %sm %ss", s);
Or even compact!
String.format("%sh %sm %ss", myString.split(":"));
String time = "1:31:25";
String formattedTime = time.replaceFirst(":","h ").replaceFirst(":","m ").concat("s");
String input = "1:31:25";
String[] tokens = input.split(":");
String output = tokens[0] + "h " + tokens[1] + "m " + tokens[2] + "s";
Repeated use of the String.replaceFirst() method would help you here.
Simply replace your first ':' with the 'h', then apply again for 'm' etc.
There are additional options, which may be more appropriate/robust etc. depending on your circumstances.
Regular expressions may be useful here, to help you parse/split up such a string.
Or given that you're parsing/outputting times, it may also be worth looking at SimpleDateFormat and its ability to parse/output date/time combinations.
In fact, if you're storing that date as a string, you may want to revist that decision. Storing it as a date object (of whatever variant) is more typesafe, will protect you against invalid values, and allow you to perform arithmetic etc on these.
String[] timeStr = "1:31:25".split(":");
StringBuffer timeStrBuf = new StringBuffer();
timeStrBuf.append(timeStr[0]);
timeStrBuf.append("h ");
timeStrBuf.append(timeStr[1]);
timeStrBuf.append("m ");
timeStrBuf.append(timeStr[2]);
timeStrBuf.append("s");
You can use a regular expression and substitution:
String input = "1:31:25";
String expr = "(\\d+):(\\d+):(\\d+)";
String substitute = "$1h $2m $3s";
String output = input.replaceAll(expr, substitute);
An alternative is to parse and output the String through Date:
DateFormat parseFmt = new SimpleDateFormat("HH:mm:ss");
DateFormat displayFmt = new SimpleDateFormat("H'h' mm\'m' ss's'");
Date d = parseFmt.parse(input);
output = displayFmt.format(d);
Use split()
String s = "1:31:25";
String[] temp = s.split(":");
System.out.println(s[0]+"h"+" "+s[1]+"m"+" "+s[2]+"s");

Categories

Resources