Verify and replace id to match a pattern in java? - java

I've a requirement where I'm getting a string that may or may not contain an s at the begining and then numbers that can be from 1 digit to 5 digits. Now, this string needs to be like the s and 5 digits (it cannot contain another letter), something like this:
s1 -> s00001
s12 -> s00012
s123 -> s00123
s1234 -> s01234
s12345 -> s12345
Because the s may or may not come, I need to check that too before adding the leading zeros.
This is what I got so far but is it there a better solution for this (maybe with regular expresions?
private String formatStoreNumber(String storeNumber) {
if(storeNumber.contains("s")) {
storeNumber = storeNumber.replace("s", "");
}
storeNumber = StringUtils.leftPad(storeNumber, 5, '0');
storeNumber = "s" + storeNumber;
return storeNumber;
}

You can try the below solution :
private static String formatStoreNumber(String storeNumber) {
String strWithoutS = storeNumber.replaceAll("S", "");
String result = "S" + ("00000" + strWithoutS).substring(strWithoutS.length());
return result;
}
Below are the input and respective output:
Input : S14666| Output : S14666
Input : 1 | Output : S00001
Input : 12 | Output : S00012
Input : 123 | Output : S00123
Input : 1234 | Output : S01234
Input : 12345 | Output : S12345

Related

How to read Java files with contain many splits

BB [FL:60 BT:10 SG:20 MK:10 | 12]
I have above data on a text file and I need to get integer values separately
In brief first BB represent food type
with ":" split represents materials
and with "|" represent time to make it
How can i get those 5 parameters in java using File reader Thank you
Use a regex matcher here, and iterate over your input string, matching pure numbers as you go along:
String input = "BB [FL:60 BT:10 SG:20 MK:10 | 12]";
String regex = "\\d+(?=[^0-9.])";
List<Integer> vals = new ArrayList<>();
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
while (m.find()) {
vals.add(Integer.parseInt(m.group(0)));
}
for (int val : vals) {
System.out.println("Found an integer: " + val);
}
Found an integer: 60
Found an integer: 10
Found an integer: 20
Found an integer: 10
Found an integer: 12
Demo
Split, split, trim & split:
-> String code = "BB [FL:60 BT:10 SG:20 MK:10 | 12]"
| Added variable code of type String with initial value "BB [FL:60 BT:10 SG:20 MK:10 | 12]"
-> String[] mattime = code.split ("[\\]\\[\\|]");
| Modified variable mattime of type String[] with initial value [Ljava.lang.String;#2286778
| Update overwrote variable mattime
-> mattime [1]
| Expression value is: "FL:60 BT:10 SG:20 MK:10 "
| assigned to temporary variable $32 of type String
-> String[] elem = mattime [1].split (" ")
| Modified variable elem of type String[] with initial value [Ljava.lang.String;#13a5fe33
| Update overwrote variable elem
-> for (String e: elem) println (e);
FL:60
BT:10
SG:20
MK:10
-> for (String e: elem) {println (e); String [] kv = e.trim().split (":") ; println (kv[0] + " : " + Integer.parseInt (kv[1])); }
FL:60
FL : 60
BT:10
BT : 10
SG:20
SG : 20
MK:10
MK : 10

Java Regular Expression not worked

I have the following string source:
String source= "$This-is-(…-“demo”";
I need the result with separation of one desh (-) only with in between words like:
This-is-demo
I remove special characters and replace it with character "-"
String result = source.replaceAll("[^\\p{L}\\p{Z}]" + "\\s*", "-");
The results of running the program result="-This-is-----demo-".
I use the following command with the expectation of removing the character "-" if it is greater than 2.
result.replaceAll("(--|---|----|-----|------|-------|--------|---------|----------)", "-")
my results: -This-is---demo- it incorrectly
FULL CODE
public static void main(String[] args) {
String source = "$This-is-(…-“demo”";
String result= a.replaceAll("[^\\p{L}\\p{Z}]" + "\\s*", "-").trim().replaceAll("(--|---|----|-----|------|-------|--------|---------|----------)", "-");
System.out.println(result);
}
I have seen your problem and then resolved it. Use following in your code:
source.replaceAll("[\\p{P}\\p{S}]", " ").trim().replaceAll("( | | | | )", "-");
It gives the desired result string which you want.

String#replaceAll() to replace *anything but a =* group

I have a parameter of key-value like this:
sign="aaaabbbb="
And I want to get the parameter name sign and the value "aaaabbb="(with quote signs)
I thought I could split the string with = to get the first elem of the array which is the parameter name and do a String.replaceAll() to remove the sign= to get the value. Anyway here is my sample code:
public class TestStringReplace {
public static void main(String[] argvs){
String s = "sign=\"aaaabbbb=\"";
String[] ss = s.split("=");
String value = s.replaceAll("\\[^=]+=","");
//EDIT: s.replaceAll("[^=]+=","") will not do the job either.
System.out.println(ss[0]);
System.out.println(value);
}
}
but the output shows this:
sign
sign="aaaabbbb="
Why \\[^=]+= not matching sign= and replace it with empty string here?Quite a newbie of Java regex, need some help.
Thanks in advance.
In Java you can use the following:
String str = "sign=\"aaaabbbb=\"";
String var1 = str.substring(0, str.indexOf('='));
String var2 = str.substring(str.indexOf('=')+1);
System.out.println("var1="+var1+", var2="+var2);
The above would have the following output:
var1=sign, var2="aaaabbbb="
Try the following regex ^\\w+= with replaceAll() instead of your regex:
public class TestStringReplace {
public static void main(String[] argvs){
String s = "sign=\"aaaabbbb=\"";
String[] ss = s.split("=");
String value = s.replaceAll("^\\w+=","");
System.out.println(ss[0]);
System.out.println(value);
}
}
This will remove the sign=.
You can see the DEMO here.
Note that with your "\\[^=]+=" regex you were trying to match the character [ literally in the beginning of your regex.
And it explains why you got sign="aaaabbbb=" as a result with replaceAll() which didn't replace anything because there's no match.
You're probably better off with an actual Pattern and back-references here.
For instance:
String[] test = {
"sign=\"aaaabbbb=\"",
// assuming a HTTP GET-styled parameter list
"blah?sign=\"aaaabbbb=\"",
"foo?sign=\"aaaabbbb=\"&blah=\"hodor\""
};
// | group 1: literal "sign"
// | | literal key-value delimiter and double quote
// | | | group 2: any character reluctantly quantified
// | | | | literal ending double quote
// | | | | | look-ahead for either "&" or end
// | | | | |
Pattern p = Pattern.compile("(sign)=\"(.+?)\"(?=$|&)");
Matcher m = null;
for (String s: test) {
m = p.matcher(s);
while (m.find()) {
System.out.printf(
"Found key: \"%s\" and value: \"%s\"%n", m.group(1), m.group(2)
);
}
}
Output
Found key: "sign" and value: "aaaabbbb="
Found key: "sign" and value: "aaaabbbb="
Found key: "sign" and value: "aaaabbbb="
Notes
I'm assuming a HTTP GET styled parameter list, but maybe you don't need to actually check for a next parameter key-value pair delimiter (i.e. &) - in which case you can remove the & part
I'm also assuming you want the "s out of your value back-reference, which kind of makes the following & check useless
Your current pattern for the replaceAll invocation will match as follows:
// | literal "[" (double-escaped)
// ||literal "^" or "=" (in character class)
// || | ... greedily quantified (1+ occurrences)
// || || literal "="
"\\[^=]+="
Finally, if you really, really want to use String#replaceAll for this, here's a slightly different pattern than the one above:
for (String s: test) {
System.out.println(
s.replaceAll(
".*(sign)=\"(.+?)\"(?=$|&).*",
"Found key: \"$1\" and value: \"$2\""
)
);
}
It still uses back-references and will produce the same result, albeit in a uglier way: you can't reuse the $1 and $2 group values, since you're creating a new String replacing the original one.
Last possible solution, using String#'split. This is the ugliest as it won't work well with a list of parameters:
for (String s: test) {
System.out.println(
// | negative look-behind for start of input
// | | literal "="
// | | | literal "
// | | |
Arrays.toString(s.split("(?<!^)=\""))
);
}
Output
[sign, aaaabbbb]
[blah?sign, aaaabbbb] --> yuck
[foo?sign, aaaabbbb, &blah, hodor"] --> yuck again
The double slash is a mistake, because it is escaping the [ to a literal [, which will never match.
Instead, do this:
String name = s.replaceAll("=.*", "");
String value = s.replaceAll(".*?=", "");

Java regex replace values

I am trying to replace certain values from a string using java regex
for example the string looks like
:20:1234
6789
:28G::xyz
|20:3456
1234
|29C:pqr
:20|9876
I want to replace tag 20 value (may be multi line value) for second occurrence
|20:3456
1234
with new value(may be multi line value) 6789 so the final replacement string i am expecting is
:20:1234
6789
:28G::xyz
|20:6789
|29C:pqr
:20|9876
Try this regex:
String str = ":20:1234\n 6789\n:28G::xyz\n|20:3456\n 1234\n|29C:pqr\n:20|9876 \n|20:3456\n :20:1234\n";
str = str.replaceAll("(\\|20:)[\\s\\S]*?(?=[|:])","$1" + "6789\n");
Here it is checking until it reaches to anything other than | or :, so that it doesn't pick all.
This should work (tested):
str.replaceAll("(\\|" + "20" + ":)[^|:]*\n","$1" + "6789" + "\n");

Regex positive lookbehind woes

My goal is to match the first 0 and everything after that zero in a decimal value. If the first decimal place is a zero then I want to match the decimal too. If there is no decimal then capture nothing.
Here are some examples of what I want:
180.570123 // should capture the "0123" on the end
180.570 // should capture the "0" on the end
180.0123 // should capture the ".0123" on the end
180.0 // should capture the ".0" on the end
180123 // should capture nothing
180 // should capture nothing
If the first decimal place is a 0 then making the match is easy:
(\.0.*)
My problem is matching when the first decimal place is not a 0. I believe positive lookbehind will fix this issue, but I am not able to get it to work correctly. Here is one regex I have tried:
(?<=^.*\..*)0.*
This regex will eventually be used in Java.
UPDATE:
I am going to use this regex to get rid of numbers and possibly a decimal point on the end of a string using Java's replaceAll method. I will do this by replacing the capture group with an empty string. Here is a better example of what I want.
String case1 = "180.570123";
String case2 = "180.570";
String case3 = "180.0123";
String case4 = "180.0";
String case5 = "180123";
String case6 = "180";
String result = null;
result = case1.replaceAll( "THE REGEX I NEED", "" );
System.out.println( result ); // should print 180.57
result = case2.replaceAll( "THE REGEX I NEED", "" );
System.out.println( result ); // should print 180.57
result = case3.replaceAll( "THE REGEX I NEED", "" );
System.out.println( result ); // should print 180
result = case4.replaceAll( "THE REGEX I NEED", "" );
System.out.println( result ); // should print 180
result = case5.replaceAll( "THE REGEX I NEED", "" );
System.out.println( result ); // should print 180123
result = case6.replaceAll( "THE REGEX I NEED", "" );
System.out.println( result ); // should print 180
Also, I am testing these regexs at http://gskinner.com/RegExr/
You can use this expression:
\.[1-9]*(0\d*)
And what you want will be in the first capturing group. (Except the decimal point.)
If you want to capture the decimal point too, you can use:
(?:\.[1-9]+|(?=\.))(\.?0\d*)
Example (online):
Pattern p = Pattern.compile("(?:\\.[1-9]+|(?=\\.))(\\.?0\\d*)");
String[] strs = {"180.570123", "180.570", "180.0123", "180.0", "180123", "180", "180.2030405"};
for (String s : strs) {
Matcher m = p.matcher(s);
System.out.printf("%-12s: Match: %s%n", s,
m.find() ? m.group(1) : "n/a");
}
Output:
180.570123 : Match: 0123
180.570 : Match: 0
180.0123 : Match: .0123
180.0 : Match: .0
180123 : Match: n/a
180 : Match: n/a
180.2030405 : Match: 030405
I would write a small function to do the extracting instead of regex.
private String getZeroPart(final String s) {
final String[] strs = s.split("\\.");
if (strs.length != 2 || strs[1].indexOf("0") < 0) {
return null;
} else {
return strs[1].startsWith("0") ? "." + strs[1] : strs[1].substring(strs[1].indexOf("0"));
}
}
to test it:
final String[] ss = { "180.570123", "180.570", "180.0123",
"180.0", "180123", "180", "180.2030405","180.5555" };
for (final String s : ss) {
System.out.println(getZeroPart(s));
}
output:
0123
0
.0123
.0
null
null
030405
null
update
based on the EDIT of the question. do some changes on the method to get the right number:
private String cutZeroPart(final String s) {
final String[] strs = s.split("\\.");
if (strs.length != 2 || strs[1].indexOf("0") < 0) {
return s;
} else {
return strs[1].startsWith("0") ? strs[0] : s.substring(0, strs[0].length() + strs[1].indexOf("0") + 1);
}
}
output:
180.570123 -> 180.57
180.570 -> 180.57
180.0123 -> 180
180.0 -> 180
180123 -> 180123
180 -> 180
180.2030405 -> 180.2
180.5555 -> 180.5555
Lookbehinds might be overkill. This one worked well-->
/\.\d*(0\d*)/
You can try this :
Matcher m = Pattern.compile("(?<=(\\.))(\\d*?)(0.*)").matcher("180.2030405");
String res="";
if(m.find()){
if(m.group(2).equals("")){
res = "."+m.group(3);
}
else{
res = m.group(3);
}
}

Categories

Resources