Here i want to validate filename using regex in java. i implemented below code but this is not works for me for 3rd type file.
Can i check prefix and extenstion in regex ???
My validate filename looks like these 3 ways
1) prefix_digit.digit.extenstion example : AB_1.1.fuij (Here fuij is my extension)
2) prefix_digit.digit.digit.extenstion example : AB_1.1.1.fuij
3) prefix_digit.digit.B/P.digit.extensionexample : AB_1.1.B.1.fuij
Only these 3 types of file valid. 3rd one is beta and pilot version files. if beta and pilot version file is there than is should be like this which i mentioned above
I am going to write some valid and invalid files
**Valid :**
AB_1.1.fuij
AB_1.4.fuij
AB_1.1.1.fuij
AB_1.1.B.1.fuij
AB_3.4.P.7.fuij
***Invalid :***
AB_0.1.fuij
AB_1.B.1.1.fuij(B/P should be place on 3rd always)
AB_1.2.B.0.fuij
CODE :
import java.util.ArrayList;
import java.util.regex.Pattern;
public class democlass {
/**
* Test harness.
*/
public static void main(String[] args) {
ArrayList<String> demoversion = new ArrayList<String>();
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.1.fuij"));
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.B.fuij"));
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.1.1.fuij"));
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.P.1.1.fuij"));
System.out.println("Result >>>>>>>>>>>> "
+isFileValid("AB_1.1.B.1.fuij"));
}
private static boolean isFileValid(String input)
{
String regexFinalBugFix = "^\\d+\\.\\d+\\.\\d+$";
String regexFinal = "^\\d+\\.\\d+$";
String regexBetaPilot = "^\\d+\\.\\d+\\.\\[BP]+\\.\\d+$";
final Pattern pattern1 = Pattern.compile(regexFinal);
final Pattern pattern2 = Pattern.compile(regexBetaPilot);
final Pattern pattern3 = Pattern.compile(regexFinalBugFix);
String inputVersion = null;
int suffixIndex = input.lastIndexOf(".");
int prefixIndex = input.lastIndexOf("_");
if (suffixIndex > 0 && prefixIndex > 0) {
inputVersion = input.substring(prefixIndex + 1,
suffixIndex);
String prefixString1 = input.substring(0, 3);
String suffixString1 = input.substring(suffixIndex);
if(prefixString1.equals("AB_") && suffixString1.equals(".fuij"))
{
if (pattern1.matcher(inputVersion).matches()
|| pattern2.matcher(inputVersion).matches()
|| pattern3.matcher(inputVersion).matches()) {
return true;
}
return false;
}
return false;
}
return false;
}
}
OUTPUT :
Result >>>>>>>>>>>> true
Result >>>>>>>>>>>> false
Result >>>>>>>>>>>> true
Result >>>>>>>>>>>> false
Result >>>>>>>>>>>> false : It should be valid but it is false, why??
Your regexBetaPilot is wrong: you are escaping the opening bracket of the [BP] class. Try this instead:
String regexBetaPilot = "^\\d+\\.\\d+\\.[BP]+\\.\\d+$";
You can easily combine all three patterns into a single pattern:
String regex = "\\d+\\.(\\d+\\.([BP]+\\.)?)?\\d+";
You don't need the anchors (^ and $). Since you are using matches() instead of find(), it will always try to match the entire string.
EDIT I left in the + after [BP] because that's what you had in your original code. However, if you want to match a single B or P, then you should remove the + from the pattern.
You are escaping the opening bracket of [BP], so it tries to find a [ in the string.
This works:
String regexBetaPilot = "^\\d+\\.\\d+\\.[BP]+\\.\\d+$";
Something like this should work with AB being static:
Regular Expression: AB_\d+\.\d+((\.\d){0,1}|\.[BP]\.\d+)\.fuij
as a Java string AB_\\d+\\.\\d+((\\.\\d){0,1}|\\.[BP]\\.\\d+)\\.fuij
This misses two of your listed invalids, but I was unsure why they should be invalid. I can halep more if you explain the rules for success / failure better?
You can simplify your regular expression to
AB_\d+\.\d+(?:(?:\.[BP])?\.\d+)?\.fuij
This matches AB_digits.digits. Then comes an optional .digits, .B.digits or .P.digits. And finally matches .fuij. From your examples, there might be only a single B or P. If you wish to match multiple Bs and Ps, just add the + again.
And then your isFileValid() function might be reduced to
private static boolean isFileValid(String input)
{
final String re = "AB_\\d+\\.\\d+(?:(?:\\.[BP])?\\.\\d+)?\\.fuij";
final Pattern pattern = Pattern.compile(re);
return pattern.matcher(input).matches();
}
Related
I have a php code as shown below which validates the answer at Line A which user enters in a html form.
When user enters any answer with apostrophe in the html input field form, I am getting the error message Secret Answer is Invalid.
For example: On entering Hello World', I am getting the error message Secret Answer is Invalid from Line Z.
//response
$response_error = new error();
$response_error->field = SECRET_response;
if($response != "" && $service->validAnswer($answer) != 'true'){ // Line A
$response_error->inError = true;
$response_error->errorMessage = SECRET_response.ISINVALID; // Line Z
} else {
$response_error->inError = false;
}
The Java code/method belonging to the validAnswer method used at Line A above is:
public static boolean validAnswer(String answer) {
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\- ]+$"); // Line B
Matcher b = a.matcher(answer);
logger.info("validAnswer: mmatches(): " + (b.matches()) + " a: " + a);
return b.matches();
}
Problem Statement:
I am wondering what changes I need to make in the java code above so that it takes apostrophe in the html input form.
This is what I have tried in the Java code:
I have put ' in at the end of [ ] inside of it. On trying that, it doesn't seem to work.
public static boolean validAnswer(String answer) {
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\-' ]+$"); // Line A
Matcher b = a.matcher(answer);
logger.info("validAnswer: mmatches(): " + (b.matches()) + " a: " + a);
return b.matches();
}
Calling Java from PHP just to use a regex is very weird and inefficient. PHP has regex support of course, so you don't need Java for that.
Anyway, your latest code works perfectly:
import java.util.regex.*;
public class Test
{
public static boolean validAnswer(String answer)
{
Pattern a = Pattern.compile("^(?=.*\\S)[a-zA-Z0-9éèàêâçîëïÇÉÔÂÊÎÔÛËÏÀùÙ!#%&$%*\\-' ]+$");
Matcher b = a.matcher(answer);
return b.matches();
}
public static void main(String args[])
{
System.out.println(validAnswer("Hello World'"));
}
}
Output:
true
So I guess you didn't recompile your code after modifying it.
I want to convert a component version (for example 2.6.0) to this form G02R06C00. I think it's possible with regex and pattern with Java but I don't found how. I have seen examples to match a string against a pattern (in this case the regex would be G\d\dR\d\dC\d\d I guess), but I don't find how to convert a string to other string with a pattern. Thanks in advance.
What I have done is:
String gorocoVersion = version.replaceAll("(\\d*)\\.(\\d*)\\.(\\d*)", "G$1R$2C$3");
that produces G2R6C0, it's missing yet to add 0 to match 2 digits.
So, I have to split input string before and I can't anymore use replaceAll, that's why I was looking for more clever option that automatically add 0 before simple digit too according to the output pattern G\d\dR\d\dC\d\d, like we can find in word or excel
Something that works with snapshot version but it's very ugly :
/**
* #return version in G00R00C00(-SNAPSHOT) format.
*/
private String formatVersion() {
String gorocoVersion = "";
if (StringUtils.isNotBlank(version)) {
String[] versionTab = version.split("\\.");
String partG = String.format("%02d", Integer.parseInt(versionTab[0]));
String partR = String.format("%02d", Integer.parseInt(versionTab[1]));
String partC = versionTab[2];
String snapshotSuffix = "-SNAPSHOT";
if (partC.endsWith(snapshotSuffix)) {
partC = String.format("%02d",
Integer.parseInt(partC.substring(0, partC.indexOf('-')))) + snapshotSuffix;
} else {
partC = String.format("%02d", Integer.parseInt(partC));
}
gorocoVersion = "G" + partG + "R" + partR + "C" + partC;
}
return gorocoVersion;
}
Try this method:
private static String formatVersion(String version) {
Pattern pattern = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)(-SNAPSHOT)*$");
Matcher matcher = pattern.matcher(version);
if (matcher.find()) {
return String.format("G%02dR%02dC%02d", Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher.group(3)));
} else {
throw new IllegalArgumentException("Unsupported version format");
}
}
Output for the version param value 2.6.0:
G02R06C00
Thanks a lot Ilya, here my final code which accepts SNAPSHOT and also x.y versions :
private String formatVersion(String version) {
if (StringUtils.isNotBlank(version)) {
Pattern pattern = Pattern.compile("^(\\d+)\\.(\\d+)\\.?(\\d+)?(-\\w*)?");
Matcher matcher = pattern.matcher(version);
if (matcher.find()) {
return String.format("G%02dR%02dC%02d%s", Integer.parseInt(matcher.group(1)),
Integer.parseInt(matcher.group(2)),
matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 0,
matcher.group(4) != null ? matcher.group(4) : "");
}
}
return version;
}
With this code 2.6 gives G02R06C00 and 2.6.1-SNAPSHOT gives G02R06C01-SNAPSHOT, perfect :)
String can be like below. Using java1.6
String example = "<number>;<name-value>;<name-value>";
String abc = "+17005554141;qwq=1234;ddd=ewew;otg=383";
String abc = "+17005554141;qwq=123454";
String abc = "+17005554141";
I want to remove qwq=1234 if present from String. qwq is fixed and its value can VARY like for ex 1234 or 12345 etc
expected result :
String abc = "+17005554141;ddd=ewew;otg=383";
String abc = "+17005554141"; \\removed ;qwq=123454
String abc = "+17005554141";
I tried through
abc = abc.replaceAll(";qwq=.*;", "");
but not working.
I came up with this qwq=\d*\;? and it works. It matches for 0 or more decimals after qwq=. It also has an optional parameter ; since your example seems to include that this is not always appended after the number.
I know the question is not about javascript, but here's an example where you can see the regex working:
const regex = /qwq=\d*\;?/g;
var items = ["+17005554141;qwq=123454",
"+17005554141",
"+17005554141;qwq=1234;ddd=ewew;otg=383"];
for(let i = 0; i < items.length; i++) {
console.log("Item before replace: " + items[i]);
console.log("Item after replace: " + items[i].replace(regex, "") + "\n\n");
}
You can use regex for removing that kind of string like this. Use this code,
String example = "+17005554141;qwq=1234;ddd=ewew;otg=383";
System.out.println("Before: " + example);
System.out.println("After: " + example.replaceAll("qwq=\\d+;?", ""));
This gives following output,
Before: +17005554141;qwq=1234;ddd=ewew;otg=383
After: +17005554141;ddd=ewew;otg=383
.* applies to multi-characters, not limited to digits. Use something that applies only to bunch of digits
abc.replaceAll(";qwq=\\d+", "")
^^
Any Number
please try
abc = abc.replaceAll("qwq=[0-9]*;", "");
If you don't care about too much convenience, you can achieve this by just plain simple String operations (indexOf, replace and substring). This is maybe the most legacy way to do this:
private static String replaceQWQ(String target)
{
if (target.indexOf("qwq=") != -1) {
if (target.indexOf(';', target.indexOf("qwq=")) != -1) {
String replace =
target.substring(target.indexOf("qwq="), target.indexOf(';', target.indexOf("qwq=")) + 1);
target = target.replace(replace, "");
} else {
target = target.substring(0, target.indexOf("qwq=") - 1);
}
}
return target;
}
Small test:
String abc = "+17005554141;qwq=1234;ddd=ewew;otg=383";
String def = "+17005554141;qwq=1234";
System.out.println(replaceQWQ(abc));
System.out.println(replaceQWQ(def));
outputs:
+17005554141;ddd=ewew;otg=383
+17005554141
Another one:
abc.replaceAll(";qwq=[^;]*;", ";");
You must to use groups in replaceAll method.
Here is an example:
abc.replaceAll("(.*;)(qwq=\\d*;)(.*)", "$1$3");
More about groups you can find on: http://www.vogella.com/tutorials/JavaRegularExpressions/article.html
In my file I have below data, everything is string
Input
"abcd","12345","success,1234,out",,"hai"
The output should be like below
Column 1: "abcd"
Column 2: "12345"
Column 3: "success,1234,out"
Column 4: null
Column 5: "hai"
We need to use comma as a delimiter , the null value is comming without double quotes.
Could you please help me to find a regular expression to parse this data
You could try a tool like CSVReader from OpenCsv https://sourceforge.net/projects/opencsv/
You can even configure a CSVParser (used by the reader) to output null on several conditions. From the doc :
/**
* Denotes what field contents will cause the parser to return null: EMPTY_SEPARATORS, EMPTY_QUOTES, BOTH, NEITHER (default)
*/
public static final CSVReaderNullFieldIndicator DEFAULT_NULL_FIELD_INDICATOR = NEITHER;
You can use this Regular Expression
"([^"]*)"
DEMO: https://regex101.com/r/WpgU9W/1
Match 1
Group 1. 1-5 `abcd`
Match 2
Group 1. 8-13 `12345`
Match 3
Group 1. 16-32 `success,1234,out`
Match 4
Group 1. 36-39 `hai`
Using the ("[^"]+")|(?<=,)(,) regex you may find either quoted strings ("[^"]+"), which should be treated as is, or commas preceded by commas, which denote null field values. All you need now is iterate through the matches and check which of the two capture groups defined and output accordingly:
String input = "\"abcd\",\"12345\",\"success,1234,out\",,\"hai\"";
Pattern pattern = Pattern.compile("(\"[^\"]+\")|(?<=,)(,)");
Matcher matcher = pattern.matcher(input);
int col = 1;
while (matcher.find()) {
if (matcher.group(1) != null) {
System.out.println("Column " + col + ": " + matcher.group(1));
col++;
} else if (matcher.group(2) != null) {
System.out.println("Column " + col + ": null");
col++;
}
}
Demo: https://ideone.com/QmCzPE
Step #1:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "(,,)";
final String string = "\"abcd\",\"12345\",\"success,1234,out\",,\"hai\"\n"
+ "\"abcd\",\"12345\",\"success,1234,out\",\"null\",\"hai\"";
final String subst = ",\"null\",";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);
// The substituted value will be contained in the result variable
final String result = matcher.replaceAll(subst);
System.out.println("Substitution result: " + result);
Original Text:
"abcd","12345","success,1234,out",,"hai"
Transformation: (with null)
"abcd","12345","success,1234,out","null","hai"
Step #2: (use REGEXP)
"([^"]*)"
Result:
abcd
12345
success,1234,out
null
hai
Credits:
Emmanuel Guiton [https://stackoverflow.com/users/7226842/emmanuel-guiton] REGEXP
You can also use the Replace function:
final String inuput = "\"abcd\",\"12345\",\"success,1234,out\",,\"hai\"";
System.out.println(inuput);
String[] strings = inuput
.replaceAll(",,", ",\"\",")
.replaceAll(",,", ",\"\",") // if you have more then one null successively
.replaceAll("\",\"", "\";\"")
.replaceAll("\"\"", "")
.split(";");
for (String string : strings) {
String output = string;
if (output.isEmpty()) {
output = null;
}
System.out.println(output);
}
I have a rather complex (to me it seems rather complex) problem that I'm using regular expressions in Java for:
I can get any text string that must be of the format:
M:<some text>:D:<either a url or string>:C:<some more text>:Q:<a number>
I started with a regular expression for extracting the text between the M:/:D:/:C:/:Q: as:
String pattern2 = "(M:|:D:|:C:|:Q:.*?)([a-zA-Z_\\.0-9]+)";
And that works fine if the <either a url or string> is just an alphanumeric string. But it all falls apart when the embedded string is a url of the format:
tcp://someurl.something:port
Can anyone help me adjust the above reg exp to extract the text after :D: to be either a url or a alpha-numeric string?
Here's an example:
public static void main(String[] args) {
String name = "M:myString1:D:tcp://someurl.com:8989:C:myString2:Q:1";
boolean matchFound = false;
ArrayList<String> values = new ArrayList<>();
String pattern2 = "(M:|:D:|:C:|:Q:.*?)([a-zA-Z_\\.0-9]+)";
Matcher m3 = Pattern.compile(pattern2).matcher(name);
while (m3.find()) {
matchFound = true;
String m = m3.group(2);
System.out.println("regex found match: " + m);
values.add(m);
}
}
In the above example, my results would be:
myString1
tcp://someurl.com:8989
myString2
1
And note that the Strings can be of variable length, alphanumeric, but allowing some characters (such as the url format with :// and/or . - characters
You mention that the format is constant:
M:<some text>:D:<either a url or string>:C:<some more text>:Q:<a number>
Capture groups can do this for you with the pattern:
"M:(.*):D:(.*):C:(.*):Q:(.*)"
Or you can do a String.split() with a pattern of "M:|:D:|:C:|:Q:". However, the split will return an empty element at the first index. Everything else will follow.
public static void main(String[] args) throws Exception {
System.out.println("Regex: ");
String data = "M:<some text>:D:tcp://someurl.something:port:C:<some more text>:Q:<a number>";
Matcher matcher = Pattern.compile("M:(.*):D:(.*):C:(.*):Q:(.*)").matcher(data);
if (matcher.matches()) {
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println(matcher.group(i));
}
}
System.out.println();
System.out.println("String.split(): ");
String[] pieces = data.split("M:|:D:|:C:|:Q:");
for (String piece : pieces) {
System.out.println(piece);
}
}
Results:
Regex:
<some text>
tcp://someurl.something:port
<some more text>
<a number>
String.split():
<some text>
tcp://someurl.something:port
<some more text>
<a number>
To extract the URL/text part you don't need the regular expression. Use
int startPos = input.indexOf(":D:")+":D:".length();
int endPos = input.indexOf(":C:", startPos);
String urlOrText = input.substring(startPos, endPos);
Assuming you need to do some validation along with the parsing:
break the regex into different parts like this:
String m_regex = "[\\w.]+"; //in jsva a . in [] is just a plain dot
String url_regex = "."; //theres a bunch online, pick your favorite.
String d_regex = "(?:" + url_regex + "|\\p{Alnum}+)"; // url or a sequence of alphanumeric characters
String c_regex = "[\\w.]+"; //but i'm assuming you want this to be a bit more strictive. not sure.
String q_regex = "\\d+"; //what sort of number exactly? assuming any string of digits here
String regex = "M:(?<M>" + m_regex + "):"
+ "D:(?<D>" + d_regex + "):"
+ "C:(?<D>" + c_regex + "):"
+ "Q:(?<D>" + q_regex + ")";
Pattern p = Pattern.compile(regex);
Might be a good idea to keep the pattern as a static field somewhere and compile it in a static block so that the temporary regex strings don't overcrowd some class with basically useless fields.
Then you can retrieve each part by its name:
Matcher m = p.matcher( input );
if (m.matches()) {
String m_part = m.group( "M" );
...
String q_part = m.group( "Q" );
}
You can go even a step further by making a RegexGroup interface/objects where each implementing object represents a part of the regex which has a name and the actual regex. Though you definitely lose the simplicity makes it harder to understand it with a quick glance. (I wouldn't do this, just pointing out its possible and has its own benefits)