replace char in specific pattern or after specific character - java

The task at hand is to replace "-" with "/" in a birthday format e.g. 03-12-89 -> 03/12/89. However, the "-" must be able to appear elsewhere in the string e.g. "My-birthday-is-on-the: 03/12/89".
I have tried creating substrings, replace the "-" in the birthday part and then combine the strings again. However, that solution is inflexible and fails the testcases.
I'm thinking I must be able to do this with a regular expression, although I seem unable to construct it. So now I'm back to: String newStr = input.replace("-", "/"); Which remove all instances of "-" which I don't want.
Can anyone help?

You can use the following regex:
(?<=\d{2})-
with replacement \/ (no need to escape it in Java)
INPUT:
My-birthday-is-on-the: 03-12-89
OUTPUT:
My-birthday-is-on-the: 03/12/89
demo
Code:
String input = "My-birthday-is-on-the: 03-12-89";
System.out.println(input.replaceAll("(?<=\\d{2})-", "/"));
OUTPUT:
My-birthday-is-on-the: 03/12/89

The easiest way which comes to mind is just match \d{2}-\d{2}-\d{2}, with capture groups. Then, use those captured numbers to rebuild the birthdate the way you want it. Something like this:
String input = "My-birthday-is-on-the: 03/12/89";
input = input.replaceAll("\\b(\\d{2})-(\\d{2})-(\\d{2})\\b", "$1/$2/$3");
Demo
The advantage of specifying the full pattern is that it avoids the chance of matching anything other than a 6 digit dash-separated birthday.
Edit:
Based on your comment below, it sounds like maybe you want to do this replacement on a two dash separated number, with any number of digits. In this case, we can slightly modify the above code to the following:
String input = "Your policy number is: 123-45-6789.";
input = input.replaceAll("\\b(\\d+)-(\\d+)-(\\d+)\\b", "$1/$2/$3");

Related

Why is my String array length 3 instead of 2?

I'm trying to understand regex. I wanted to make a String[] using split to show me how many letters are in a given string expression?
import java.util.*;
import java.io.*;
public class Main {
public static String simpleSymbols(String str) {
String result = "";
String[] alpha = str.split("[\\+\\w\\+]");
int alphaLength = alpha.length;
// System.out.print(alphaLength);
String[] charCount = str.split("[a-z]");
int charCountLength = charCount.length;
System.out.println(charCountLength);
}
}
My input string is "+d+=3=+s+". I split the string to count the number of letters in string. The array length should be two but I'm getting three. Also, I'm trying to make a regex to check the pattern +b+, with b being any letter in the alphabet? Is that correct?
So, a few things pop out to me:
First, your regex looks correct. If you're ever worried about how your regex will perform, you can use https://regexr.com/ to check it out. Just put your regex on the top and enter your string in the bottom to see if it is matching correctly
Second, upon close inspection, I see you're using the split function. While it is convenient for quickly splitting strings, you need to be careful as to what you are splitting on. In this case, you're removing all of the strings that you were initially looking at, which would make it impossible to find. If you print it out, you would notice that the following shows (for an input string of +d+=3=+s+):
+
+=3=+
+
Which shows that you accidentally cut out what you were looking to find in the first place. Now, there are several ways of fixing this, depending on what your criteria is.
Now, if what you wanted was just to separate on all +s and it doesn't matter that you find only what is directly bounded by +s, then split works awesome. Just do str.split("+"), and this will return you a list of the following (for +d+=3=+s+):
d
=3=
s
However, you can see that this poses a few problems. First, it doesn't strip out the =3= that we don't want, and second, it does not truly give us values that are surrounded by a +_+ format, where the underscore represents the string/char you're looking for.
Seeing as you're using +w, you intend to find words that are surrounded by +s. However, if you're just looking to find one character, I would suggest using another like [a-z] or [a-zA-Z] to be more specific. However, if you want to find multiple alphabetical characters, your pattern is fine. You can also add a * (0 or more) or a + (1 or more) at the end of the pattern to dictate what exactly you're looking for.
I won't give you the answer outright, but I'll give you a clue as to what to move towards. Try using a pattern and a matcher to find the regex that you listed above and then if you find a match, make sure to store it somewhere :)
Also, for future reference, you should always start a function name with a lower case, at least in Java. Only constants and class names should start in a capital :)
I am trying to use split to count the number of letters in that string. The array length should be two, but I'm getting three.
The regex in the split functions is used as delimiters and will not be shown in results. In your case "str.split([a-z])" means using alphabets as delimiters to separate your input string, which makes three substrings "(+)|d|(+=3=+)|s|(+)".
If you really want to count the number of letters using "split", use 'str.split("[^a-z]")'. But I would recommend using "java.util.regex.Matcher.find()" in order to find out all letters.
Also, I'm trying to make a regex to check the pattern +b+, with b being any letter in the alphabet? Is that correct?
Similarly, check the functions in "java.util.regex.Matcher".

Regex to match a fixed sub string in a String

I am trying to write a regular expression to verify the presence of a specific number in a fixed position in a String.
String: 109300300330066611111111100000000017000656052086116020170111Name 1
Number to find: 111111111 (Staring from position 17)
I have written the following regular expression:
^.{16}(?<Ones>111111111)(.*)
My understanding is:
Let first 16 characters be whatever they are
Use the Named Capturing Group to grab the specific word
Let the rest of the characters be whatever they are
I am new to regex, is there any issue with the above approach?
Can it be done in other/better way?
I am using Java 8.
Without more details of why you're doing what you're doing, there's just one possible improvement I can see. You repeated any character 16 times at the beginning of the string rather than writing out 16 .s, which is nice and readable, but then, it would be nice to do the same for the repeated 1s:
^.{16}(?<Ones>1{9})(.*)
Otherwise, the string of 1s is hard to understand without the coder manually counting how many there are in the regex.
If you want to hard-code the ones and you know the starting position and you just wnat to know if it is there, using a regex seems unnecessary. you can use this:
String s = "109300300330066611111111100000000017000656052086116020170111Name 1";
if (s.indexOf("111111111").equals(16) doSomething();
Another possible solution without regex:
if(s.substring(16,25).equals("111111111") doSomething();
Otherwise your regex looks good.

Regex for matching multiple date formats?

Sorry if this is a noob question but I'm not very comfortable with regex and (as of now) this is a little beyond my understanding.
My dilemma is that we have a verity of ID badges that get scanned into an android application and I'm trying to parse out some dates.
For example, some dates are represented like so:
"ISS20141231" format = yyyyMMdd desired output = "20141231"
"ISS12312014" format = MMddyyyy desired output = "12312014"
"ISS12-31-2014" format = MM-dd-yyyy desired output = "12312014"
currently I have a regex pattern:
Pattern p = Pattern.compile("ISS(\\d{8})");
Matcher m = p.matcher(scanData);
which worked fine for the first two examples but recently I have realized that we also occasionally have dates which use dashes (or slashes) as separators.
Is there an efficient means for extracting these dates without having to write multiple patterns and loop through each one checking for a match?
possibly similar to: "ISS([\d{8} (\d{2}\w\d{2}\w\d{4}) (\d{4}\w\d{2}\w\d{2})])"
Thanks!!
[EDIT]
Just to make things a little bit more clear. The substring ("ISSMMddyyyy") is from a much larger string and could be located anywhere within it. So regex must search the original (200+ byte) string for a match.
If that date string is actually a substring of a larger string, and so you need the regex in order to also search for that pattern, you could modify your regex to be:
ISS([\\d\\-/]{8,10})
And then when retrieving the capture group, strip the hyphens and slashes.
String dateStr = m.group(1).replaceAll("[/\\-]", "");
You can do 2 replace i.e. replace ISS first and then replace / or -:
str = str.replaceFirst("^ISS", "").replaceAll("[/-]", "");
Or to only use a regex:
Search: ISS([0-9])([-./])([0-9])([-./])([0-9]*)
Replace: ${1}${3}${5}

How to create regex pattern for validating editext in android?

am create reg-ex for validating edit text field.am not able to validate correctly.
my condition to validate is
Example (h2/g2)
At-least have a one numerical value
slash also allowed but only one,after the "/" must have one numerical value.
alphabets also allowed
How to create reg-ex for this condition.Can any one know please help me to solve this problem
Seems like you want something like this: (\w*/)?\w*\d\w*
Remember that in Java you have to duplicate backslashes \\.
Adding more examples of valid and invalid texts would help.
Edit:
Answering you comment. Yes, it does:
String value = "h2/g2";
Pattern p = Pattern.compile("(\\w*/)?\\w*\\d\\w*");
Matcher m = p.matcher(value);
Log.i("tag", "matches? " + m.matches());
prints:
I/tag(12642): matches? true

How to retrieve portion of number that's within parenthesis in Java?

For part of my Java assignment I'm required to select all records that have a certain area code. I have custom objects within an ArrayList, like ArrayList<Foo>.
Each object has a String phoneNumber variable. They are formatted like "(555) 555-5555"
My goal is to search through each custom object in the ArrayList<Foo> (call it listOfFoos) and place the objects with area code "616" in a temporaryListOfFoos ArrayList<Foo>.
I have looked into tokenizers, but was unable to get the syntax correct. I feel like what I need to do is similar to this post, but since I'm only trying to retrieve the first 3 digits (and I don't care about the remaining 7), this really didn't give me exactly what I was looking for. Ignore parentheses with string tokenizer?
What I did as a temporary work-around, was...
for (int i = 0; i<listOfFoos.size();i++){
if (listOfFoos.get(i).getPhoneNumber().contains("616")){
tempListOfFoos.add(listOfFoos.get(i));
}
}
This worked for our current dataset, however, if there was a 616 anywhere else in the phone numbers [like "(555) 616-5555"] it obviously wouldn't work properly.
If anyone could give me advice on how to retrieve only the first 3 digits, while ignoring the parentheses, I would greatly appreciate it.
You have two options:
Use value.startsWith("(616)") or,
Use regular expressions with this pattern "^\(616\).*"
The first option will be a lot quicker.
areaCode = number.substring(number.indexOf('(') + 1, number.indexOf(')')).trim() should do the job for you, given the formatting of phone numbers you have.
Or if you don't have any extraneous spaces, just use areaCode = number.substring(1, 4).
I think what you need is a capturing group. Have a look at the Groups and capturing section in this document.
Once you are done matching the input with a pattern (for example "\((\\d+)\) \\d+-\\d+"), you can get the number in the parentheses using a matcher (object of java.util.regex.Matcher) with matcher.group(1).
You could use a regular expression as shown below. The pattern will ensure the entire phone number conforms to your pattern ((XXX) XXX-XXXX) plus grabs the number within the parentheses.
int areaCodeToSearch = 555;
String pattern = String.format("\\((%d)\\) \\d{3}-\\d{4}", areaCodeToSearch);
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(phoneNumber);
if (m.matches()) {
String areaCode = m.group(1);
// ...
}
Whether you choose to use a regular expression versus a simple String lookup (as mentioned in other answers) will depend on how bothered you are about the format of the entire string.

Categories