The homework assignment says I have to write code that validates dates in yyyy/mm/dd format.
It asks that I first check the input String so that the first part, the year is exactly 4 numbers and month is between 1 and 2 (inclusive). And if it doesn't match that criteria, i throw an exception called "InvalidDateException", (I've already wrote the class for that)
So my given example is 2016/05/12 should be considered a valid date.
Looking into how Regex works, I come to the conclusion that I would need \\d+ so that java can find numbers.
Here's my code (variable date is a String, instantiated in the method that contains this code):
int yr = date.substring(0, date.indexOf("/")).length();
int mo = date.substring(date.indexOf("/")+1, date.lastIndexOf("/")).length();
if (date.matches("\\d+") && (yr == 4) && (mo <= 2 && mo >= 1)) {
//I've put code here that outputs it as a valid date
}
So then if I put 2016/05/12, it should say that it's a valid date, however it instead goes to my error message of "InvalidDateException"
I've looked through the other regex questions on StackOverflow but I can't seem to find out why my code doesn't work.
any help is appreciated
Example 1
This would give you a straight-forward solution but you'd still need to parse the String for its components.
Pattern pattern = Pattern.compile("\\d{4}/\\d{1,2}/\\d{1,2}");
Matcher matcher = pattern.matcher(input);
if (matcher.matches())
{
// Some code here to extract the year/month/day...
}
Example 2
A better way is to group the results (with parenthesis).
Pattern pattern = Pattern.compile("(\\d{4})/(\\d{1,2})/(\\d{1,2})");
Matcher matcher = pattern.matcher(input);
if (matcher.matches())
{
int year = Integer.valueOf(matcher.group(1)); // First group
int month = Integer.valueOf(matcher.group(2)); // Second group
int day = Integer.valueOf(matcher.group(3)); // Third group
// Some code here...
}
Example 3
An even better way is to name the grouped results.
Pattern pattern = Pattern.compile("(?<year>\\d{4})/(?<month>\\d{1,2})/(?<day>\\d{1,2})");
Matcher matcher = pattern.matcher(input);
if (matcher.matches())
{
int year = Integer.valueOf(matcher.group("year")); // "year" group
int month = Integer.valueOf(matcher.group("month")); // "month" group
int day = Integer.valueOf(matcher.group("day")); // "day" group
// Some code here...
}
Example 4.a
You could use a regex builder class. This is beneficial as it has some re-usability.
public class Regex {
private StringBuilder regexBuilder = new StringBuilder();
private final String input;
private Regex(String input) {
this.input = input;
}
public static Regex of(String input) {
return new Regex(input);
}
public Regex append(String regex) {
regexBuilder.append(regex);
return this;
}
public Regex group(String groupName, String regex) {
regexBuilder.append("(?<")
.append(groupName)
.append(">")
.append(regex)
.append(")");
return this;
}
public Matcher matcher() {
return Pattern.compile(regexBuilder.toString()).matcher(input);
}
}
Example 4.b
Using the builder...
final String yearGroup = "year";
final String monthGroup = "month";
final String dayGroup = "day";
Matcher matcher =
Regex.of(input)
.group(yearGroup, "\\d{4}")
.append("/")
.group(monthGroup, "\\d{1,2}")
.append("/")
.group(dayGroup, "\\d{1,2}")
.matcher();
if (matcher.matches())
{
int year = Integer.valueOf(matcher.group(yearGroup)); // "year" group
int month = Integer.valueOf(matcher.group(monthGroup)); // "month" group
int day = Integer.valueOf(matcher.group(dayGroup)); // "day" group
// Some code here...
}
Split solution is good if you need to make further complicated validations.
public boolean isDateValid (String date) {
String[] dateElements = date.split("/");
if (dateElements.length == 3)
return isDateElementsValid(dateElements);
else
throw new RuntimeException();
}
public boolean isDateElementsValid(String[] dateElements){
String year = dateElements[0];
String month = dateElements[1];
String day = dateElements[2];
return isYearValid(year) && isMonthValid(month) && isDayValid(day);
}
Regex is good to have less code.
public boolean isDateValid (String date) {
if (date.matches("\\d{4}/\\d{1,2}/\\d{1,2}"))
return true;
else
throw new RuntimeException();
}
*Replace RuntimeException with custom implementation. Best practice will be to extend custom exception from RuntimeException.
Related
As of now, I'm parsing PDF using PDFBox later I will be parsing other documents (.docx/.doc). Using PDFBox, I'm getting all file content into one string. Now, I wanted to get complete sentence wherever a user define words matches.
For example:
... some text here..
Raman took more than 12 year to complete his schooling and now he
is pursuing higher study.
Relational Database.
... some text here ..
If user gives the input year, then it should return whole sentence.
Expected Output:
Raman took more than 12 year to complete his schooling and now he
is pursuing higher study.
I'm trying below code, but it showing nothing. Can anyone correct this
Pattern pattern = Pattern.compile("[\\w|\\W]*+[YEAR]+[\\w]*+.");
Also, If I have to include multiple words to match as OR condition, then what should I make change in my regex ?
Please note all words are in uppercase.
Do not try to put everything into the single regexp. There's a standard Java class java.text.BreakIterator which can be used to find the sentence boundaries.
public static String getSentence(String input, String word) {
Matcher matcher = Pattern.compile(word, Pattern.LITERAL | Pattern.CASE_INSENSITIVE)
.matcher(input);
if(matcher.find()) {
BreakIterator br = BreakIterator.getSentenceInstance(Locale.ENGLISH);
br.setText(input);
int start = br.preceding(matcher.start());
int end = br.following(matcher.end());
return input.substring(start, end);
}
return null;
}
Usage:
public static void main(String[] args) {
String input = "... some text...\n Raman took more than 12 year to complete his schooling and now he\nis pursuing higher study. Relational Database. \n... some text...";
System.out.println(getSentence(input, "YEAR"));
}
Pattern re = Pattern.compile("[^.!?\\s][^.!?]*(?:[.!?](?!['\"]?\\s|$) [^.!?]*)*[.!?]?['\"]?(?=\\s|$)", Pattern.MULTILINE | Pattern.COMMENTS);
Matcher reMatcher = re.matcher(result);
while (reMatcher.find()) {
System.out.println(reMatcher.group());
}
A small fix to #Tagir Valeev answer to prevent index out of bounds exceptions.
private String getSentence(String input, String word) {
Matcher matcher = Pattern.compile(word , Pattern.LITERAL | Pattern.CASE_INSENSITIVE)
.matcher(input);
if(matcher.find()) {
BreakIterator br = BreakIterator.getSentenceInstance(Locale.ENGLISH);
br.setText(input);
int start = br.preceding(matcher.start());
int end = br.following(matcher.end());
if(start == BreakIterator.DONE) {
start = 0;
}
if(end == BreakIterator.DONE) {
end = input.length();
}
return input.substring(start, end);
}
return null;
}
I want to pass date like 20140101 as its data type is integer in meta file so i have tried many regex but it always return false. Another column that is of type long with data like 0000000000000. So what is regex for both integer and long separate. Thanks
I guess a regex like this one should work for an integer:
(\d{4})(\d{2})(\d{2})
EXAMPLE
Assuming your date occupies the last digits of the long here is the regex you should use :
\d{5}(\d{4})(\d{2})(\d{2})
EXAMPLE
In Java you should be able to get the date object you seek with:
String toParse = "20140102";
Pattern pattern = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})");
Matcher matcher = pattern.matcher(toParse);
if (matcher.find()) {
int year = Integer.parseInt(matcher.group(1));
int month = Integer.parseInt(matcher.group(2));
int day = Integer.parseInt(matcher.group(3));
System.out.println(new Date(year - 1900, month - 1, day));
}
You can try it HERE
If you have a string like 20140101 and you have to test it with regex you can use this regex:
/[0-9]{8}/
Example:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class MatcherExample {
public static void main(String[] args) {
String text =
"This is the text to be searched " +
"for occurrences of the http:// pattern.";
String patternString = "/[0-9]{8}/";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
boolean matches = matcher.matches();
}
}
You could use https://regex101.com/ to test regex.
I want to validate a phone number in such Way :-
The field should allow the user to enter characters and should auto-correct. So an entry of "+1-908-528-5656" would not create an error for the user, it would just change to "19085285656".
I also want to number range between 9 to 11.
I also tried with the below code but not concluded to the final solution:
final String PHONE_REGEX = "^\\+([0-9\\-]?){9,11}[0-9]$";
final Pattern pattern = Pattern.compile(PHONE_REGEX);
String phone = "+1-908-528-5656";
phone=phone.replaceAll("[\\-\\+]", "");
System.out.println(phone);
final Matcher matcher = pattern.matcher(phone);
System.out.println(matcher.matches());
You can use simple String.matches(regex) to test any string against a regex pattern instead of using Pattern and Matcher classes.
Sample:
boolean isValid = phoneString.matches(regexPattern);
Find more examples
Here is the regex pattern as per your input string:
\+\d(-\d{3}){2}-\d{4}
Online demo
Better use Spring validation annotation for validation.
Example
// The Regex not validate mobile number, which is in internation format.
// The Following code work for me.
// I have use libphonenumber library to validate Number from below link.
// http://repo1.maven.org/maven2/com/googlecode/libphonenumber/libphonenumber/8.0.1/
// https://github.com/googlei18n/libphonenumber
// Here, is my source code.
public boolean isMobileNumberValid(String phoneNumber)
{
boolean isValid = false;
// Use the libphonenumber library to validate Number
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber swissNumberProto =null ;
try {
swissNumberProto = phoneUtil.parse(phoneNumber, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
if(phoneUtil.isValidNumber(swissNumberProto))
{
isValid = true;
}
// The Library failed to validate number if it contains - sign
// thus use regex to validate Mobile Number.
String regex = "[0-9*#+() -]*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(phoneNumber);
if (matcher.matches()) {
isValid = true;
}
return isValid;
}
Assuming your input field take any kind of character and you just want the digits.
String phone = "+1-908-528-5656";
phone=phone.replaceAll("[\\D]","");
if(phone.length()>=9 || phone.length()<=11)
System.out.println(phone);
We can use String.matches(String regex)1 to validate phone numbers using java.
Sample code snippet
package regex;
public class Phone {
private static boolean isValid(String s) {
String regex = "\\d{3}-\\d{3}-\\d{4}"; // XXX-XXX-XXXX
return s.matches(regex);
}
public static void main(String[] args) {
System.out.println(isValid("123-456-7890"));
}
}
P.S. The regex pattern we use extra '\' for escaping when we use in java string. (Try to use "\d{3}-\d{3}-\d{4}" in java program, you will get an error.
Assuming you want an optimization (which is what your comment suggests).
How bout this? (the "0" is to exclude if they give complete garbage without even a single digit).
int parse(String phone){
int num = Integer.parseInt("0"+phone.replaceAll("[^0-9]",""));
return 100000000<=num&&num<100000000000?num:-1;
}
I am not sure but removing the garbage characters parenthesis, spaces and hyphens, if you match with ^((\+[1-9]?[0-9])|0)?[7-9][0-9]{9}$ , you may validate a mobile number
private static final String PHONE_NUMBER_GARBAGE_REGEX = "[()\\s-]+";
private static final String PHONE_NUMBER_REGEX = "^((\\+[1-9]?[0-9])|0)?[7-9][0-9]{9}$";
private static final Pattern PHONE_NUMBER_PATTERN = Pattern.compile(PHONE_NUMBER_REGEX);
public static boolean validatePhoneNumber(String phoneNumber) {
return phoneNumber != null && PHONE_NUMBER_PATTERN.matcher(phoneNumber.replaceAll(PHONE_NUMBER_GARBAGE_REGEX, "")).matches();
}
One easy and simple to use java phone validation regex:
public static final String PHONE_VERIFICATION = "^[+0-9-\\(\\)\\s]*{6,14}$";
private static Pattern p;
private static Matcher m;
public static void main(String[] args)
{
//Phone validation
p = Pattern.compile(PHONE_VERIFICATION);
m = p.matcher("+1 212-788-8609");
boolean isPhoneValid = m.matches();
if(!isPhoneValid)
{
System.out.println("The Phone number is NOT valid!");
return;
}
System.out.println("The Phone number is valid!");
}
i have done testing one regex for this combination of phone numbers
(294) 784-4554
(247) 784 4554
(124)-784 4783
(124)-784-4783
(124) 784-4783
+1(202)555-0138
THIS REGEX SURELY WILL BE WORKING FOR ALL THE US NUMBERS
\d{10}|(?:\d{3}-){2}\d{4}|\(\d{3}\)\d{3}-?\d{4}|\(\d{3}\)-\d{3}-?\d{4}|\(\d{3}\) \d{3} ?\d{4}|\(\d{3}\)-\d{3} ?\d{4}|\(\d{3}\) \d{3}-?\d{4}
Building on #k_g's answers, but for US numbers.
static boolean isValidTelephoneNumber(String number) {
long num = Long.parseLong("0" + number.replaceAll("[^0-9]", ""));
return 2000000000L <= num && num < 19999999999L;
}
public static void main(String[] args) {
var numbers = List.of("+1 212-788-8609", "212-788-8609", "1 212-788-8609", "12127888609", "2127888609",
"7143788", "736103355");
numbers.forEach(number -> {
boolean isPhoneValid = isValidTelephoneNumber(number);
log.debug(number + " matches = " + isPhoneValid);
});
}
Dear, i would delete from a list, the strings that contain a date.
Ex: "1990s music groups" must be deleted.
Can I do this in java?
The regex \d{4} would probably suffice - it will match all strings containing 4 subsequent digits. You can perhaps have some more specific cases, like 19\d{2}|20\d{2}
If you are using the YYYY date format, the regular expression ^\d{4} should work for any date in the beginning of the String.
String str = "1990s music groups";
boolean shouldDelete = str.matches("^\d{4}");
if (shouldDelete) {
// Delete string
}
If you want to match the date in any part of the String, simply remove the leading ^.
//ArrayList<String> list = ....
String year = "1990";
ArrayList<String> toRemove = new ArrayList<String>();
for (String str:list) {
if (str.matches(".*"+year+".*")) {
toRemove.add(str);
}
}
for (String str:toRemove) list.remove(str);
toRemove = null;
Use a toRemove list to prevent a java.util.ConcurrentModificationException
For a more specific year rate (1970-2029) I've used:
Pattern pattern;
Matcher matcher;
String errorTag = null;
private static final String PATTERN_YEAR = "^(197\\d{1}|198\\d{1}|199\\d{1}|200\\d{1}|201\\d{1}|202\\d{1})";
...
if (filter.getName().contains("YYYY")){
pattern = Pattern.compile(PATTERN_YEAR);
matcher = pattern.matcher(filter.getValue());
if(!matcher.matches()){
errorTag= " *** The year is invalid, review the rate";
}
}
I've a long template from which I need to extract certain strings based on certain patterns. When I went through some examples I found that use of quantifiers is good in such situations.For example following is my template, from which I need to extract while and doWhile.
This is a sample document.
$while($variable)This text can be repeated many times until do while is called.$endWhile.
Some sample text follows this.
$while($variable2)This text can be repeated many times until do while is called.$endWhile.
Some sample text.
I need to extract the whole text, starting from $while($variable) till $endWhile. I then need to process the value of $variable. After that I need to insert the text between $while and $endWhile to the original text.
I've the logic of extracting the variable. But I'm not sure how to use quantifiers or pattern match here.
Can someone please provide me a sample code for this? Any help will be greatly appreciated
You can use a rather simple regex-based solution here with a Matcher:
Pattern pattern = Pattern.compile("\\$while\\((.*?)\\)(.*?)\\$endWhile", Pattern.DOTALL);
Matcher matcher = pattern.matcher(yourString);
while(matcher.find()){
String variable = matcher.group(1); // this will include the $
String value = matcher.group(2);
// now do something with variable and value
}
If you want to replace the variables in the original text, you should use the Matcher.appendReplacement() / Matcher.appendTail() solution:
Pattern pattern = Pattern.compile("\\$while\\((.*?)\\)(.*?)\\$endWhile", Pattern.DOTALL);
Matcher matcher = pattern.matcher(yourString);
StringBuffer sb = new StringBuffer();
while(matcher.find()){
String variable = matcher.group(1); // this will include the $
String value = matcher.group(2);
// now do something with variable and value
matcher.appendReplacement(sb, value);
}
matcher.appendTail(sb);
Reference:
Methods of the Pattern Class
(Sun Java Tutorial)
Methods of the Matcher Class
(Sun Java Tutorial)
Pattern JavaDoc
Matcher JavaDoc
public class PatternInString {
static String testcase1 = "what i meant here";
static String testcase2 = "here";
public static void main(String args[])throws StringIndexOutOfBoundsException{
PatternInString testInstance= new PatternInString();
boolean result = testInstance.occurs(testcase1,testcase2);
System.out.println(result);
}
//write your code here
public boolean occurs(String str1, String str2)throws StringIndexOutOfBoundsException
{ int i;
boolean result=false;
int num7=str1.indexOf(" ");
int num8=str1.lastIndexOf(" ");
String str6=str1.substring(num8+1);
String str5=str1.substring(0,num7);
if(str5.equals(str2))
{
result=true;
}
else if(str6.equals(str2))
{
result=true;
}
int num=-1;
try
{
for(i=0;i<str1.length()-1;i++)
{ num=num+1;
num=str1.indexOf(" ",num);
int num1=str1.indexOf(" ",num+1);
String str=str1.substring(num+1,num1);
if(str.equals(str2))
{
result=true;
break;
}
}
}
catch(Exception e)
{
}
return result;
}
}