How to validate regex for condition:
Password must not contain any sequence of characters immediately followed by the same sequence of characters. I am having other conditions as well and am using
(?=.*(..+)\\1)
to validate for immediate sequence repeat. And it is failing. This piece of code returns "true" for 3rd and 4th strings passed; I need it to return false. Please help.
String s2[] = {"1newAb", "newAB1", "1234567AaAa", "123456ab3434", "love", "love1"};
boolean b3;
for(int i=0; i<s2.length; i++){
b3 = s2[i].matches("^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*(..+)\\1).{5,12}$");
System.out.println("value" + b3);
}
You can try with negative look-ahead (?!.*(.{2,})\\1).
For those who are wondering what \\1 is: it represents match from group 1, which in our case is match from (.{2,})
With Ron's suggestion I found which methods in java helps; matches(), find() work differently. find() helped me.
Guido's suggestion am breaking up code for different rules. Here's my code; yet to refine it: For checking repeat of any sequence using (\S+?)\1
String regex = "(\\S+?)\\1";
String regex2 = "^(?=.*[0-9])(?=.*[a-zA-Z]).{5,12}$";
p = Pattern.compile(regex);
for (String str : s2) {
matcher = p.matcher(str);
if (matcher.find())
System.out.println(str + " got repeated: " + matcher.group(1));
else if(str.matches(regex2))
System.out.println(str + " Password correct");
else
System.out.println(str + " Password incorrect");
}
Related
I am getting file names as string as follows:
file_g001
file_g222
g_file_z999
I would like to return files that contains "g_x" where x is any number (as string). Note that the last file should not appear as the g_ is followed by an alphabet and not a number like the first 2.
I tried: file.contains("_g[0-9]*$") but this didn't work.
Expected results:
file_g001
file_g222
Are you using the method contains of String ?
If so, it does not work with regular expression.
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#contains-java.lang.CharSequence-
public boolean contains(CharSequence s)
Returns true if and only if this string contains the specified sequence of char values.
Consider using the method matches.
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#matches(java.lang.String)
Your regular expression is also fine, we'd just slightly improve that to:
^.*_g[0-9]+$
or
^.*_g\d+$
and it would likely work.
The expression is explained on the top right panel of this demo if you wish to explore/simplify/modify it.
Test
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "^.*_g[0-9]+$";
final String string = "file_g001\n"
+ "file_g222\n"
+ "file_some_other_words_g222\n"
+ "file_g\n"
+ "g_file_z999";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
I want to validate a username against these requirements:
Just accept character or digital
At least one character
I tried with
public boolean validateFormat(String input){
return Pattern.compile("^[A-Za-z0-9]+$").matcher(input).matches();
}
How can I do this one?
Try with this regex:
^(\w|\d)+$
^ indicates the start of the string
$ indicates the end of the string
\w means any word character
\d means any digit
| is the logical OR operator
Anyway, i suggest you to use an online regex tester like regex101.com .It is very helpful to quickly test regular expressions.
Hope it can help!
== UPDATE ==
In Java code:
final String regex = "^(\\w|\\d)+$";
final String string = "myCoolUsername12";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
if(matcher.matches()) {
// if you are interested only in matching the full regex
}
// Otherwise, you can iterate over the matched groups (including the full match)
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/
It may be very simple, but I am extremely new to regex and have a requirement where I need to do some regex matches in a string and extract the number in it. Below is my code with sample i/p and required o/p. I tried to construct the Pattern by referring to https://www.freeformatter.com/java-regex-tester.html, but my regex match itself is returning false.
Pattern pattern = Pattern.compile(".*/(a-b|c-d|e-f)/([0-9])+(#[0-9]?)");
String str = "foo/bar/Samsung-Galaxy/a-b/1"; // need to extract 1.
String str1 = "foo/bar/Samsung-Galaxy/c-d/1#P2";// need to extract 2.
String str2 = "foo.com/Samsung-Galaxy/9090/c-d/69"; // need to extract 69
System.out.println("result " + pattern.matcher(str).matches());
System.out.println("result " + pattern.matcher(str1).matches());
System.out.println("result " + pattern.matcher(str1).matches());
All of above SOPs are returning false. I am using java 8, is there is any way by which in a single statement I can match the pattern and then extract the digit from the string.
I would be great if somebody can point me on how to debug/develop the regex.Please feel free to let me know if something is not clear in my question.
You may use
Pattern pattern = Pattern.compile(".*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)");
See the regex demo
When used with matches(), the pattern above does not require explicit anchors, ^ and $.
Details
.* - any 0+ chars other than line break chars, as many as possible
/ - the rightmost / that is followed with the subsequent subpatterns
(?:a-b|c-d|e-f) - a non-capturing group matching any of the alternatives inside: a-b, c-d or e-f
/ - a / char
[^/]*? - any chars other than /, as few as possible
([0-9]+) - Group 1: one or more digits.
Java demo:
List<String> strs = Arrays.asList("foo/bar/Samsung-Galaxy/a-b/1","foo/bar/Samsung-Galaxy/c-d/1#P2","foo.com/Samsung-Galaxy/9090/c-d/69");
Pattern pattern = Pattern.compile(".*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)");
for (String s : strs) {
Matcher m = pattern.matcher(s);
if (m.matches()) {
System.out.println(s + ": \"" + m.group(1) + "\"");
}
}
A replacing approach using the same regex with anchors added:
List<String> strs = Arrays.asList("foo/bar/Samsung-Galaxy/a-b/1","foo/bar/Samsung-Galaxy/c-d/1#P2","foo.com/Samsung-Galaxy/9090/c-d/69");
String pattern = "^.*/(?:a-b|c-d|e-f)/[^/]*?([0-9]+)$";
for (String s : strs) {
System.out.println(s + ": \"" + s.replaceFirst(pattern, "$1") + "\"");
}
See another Java demo.
Output:
foo/bar/Samsung-Galaxy/a-b/1: "1"
foo/bar/Samsung-Galaxy/c-d/1#P2: "2"
foo.com/Samsung-Galaxy/9090/c-d/69: "69"
Because you match always the last number in your regex, I would Like to just use replaceAll with this regex .*?(\d+)$ :
String regex = ".*?(\\d+)$";
String strResult1 = str.replaceAll(regex, "$1");
System.out.println(!strResult1.isEmpty() ? "result " + strResult1 : "no result");
String strResult2 = str1.replaceAll(regex, "$1");
System.out.println(!strResult2.isEmpty() ? "result " + strResult2 : "no result");
String strResult3 = str2.replaceAll(regex, "$1");
System.out.println(!strResult3.isEmpty() ? "result " + strResult3 : "no result");
If the result is empty then you don't have any number.
Outputs
result 1
result 2
result 69
Here is a one-liner using String#replaceAll:
public String getDigits(String input) {
String number = input.replaceAll(".*/(?:a-b|c-d|e-f)/[^/]*?(\\d+)$", "$1");
return number.matches("\\d+") ? number : "no match";
}
System.out.println(getDigits("foo.com/Samsung-Galaxy/9090/c-d/69"));
System.out.println(getDigits("foo/bar/Samsung-Galaxy/a-b/some other text/1"));
System.out.println(getDigits("foo/bar/Samsung-Galaxy/9090/a-b/69ace"));
69
no match
no match
This works on the sample inputs you provided. Note that I added logic which will display no match for the case where ending digits could not be matched fitting your pattern. In the case of a non-match, we would typically be left with the original input string, which would not be all digits.
I am trying to do a replacement using regex. The relevant piece of code is as follows:
String msg =" <ClientVerificationResult>\n " +
" <VerificationIDCheck>Y</VerificationIDCheck>\n" +
" </ClientVerificationResult>\n";
String regex = "(<VerificationIDCheck>)([Y|N])(</VerificationIDCheck>)";
String replacedMsg= msg.replaceAll(regex, "$2".matches("Y") ? "$1YES$3" : "$1NO$3") ;
System.out.println(replacedMsg);
The output of this is
<ClientVerificationResult>
<VerificationIDCheck>NO</VerificationIDCheck>
</ClientVerificationResult>
When it should be
<ClientVerificationResult>
<VerificationIDCheck>YES</VerificationIDCheck>
</ClientVerificationResult>
I guess the problem is that "$2".matches("Y") is returning false. I have tried doing "$2".equals("Y"); and weird combinations inside matches() like "[Y]" or "([Y])", but still nothing.
If I print "$2" the output is Y. Any hints on what am I doing wrong?
You cannot use Java code as the replacement argument for replaceAll which is supposed to be a string only. Better use Pattern and Matcher APIs and evaluate matcher.group(2) for your replacement logic.
Suggested Code:
String msg =" <ClientVerificationResult>\n " +
" <VerificationIDCheck>Y</VerificationIDCheck>\n" +
" </ClientVerificationResult>\n";
String regex = "(<VerificationIDCheck>)([YN])(</VerificationIDCheck>)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher( msg );
StringBuffer sb = new StringBuffer();
while (m.find()) {
String repl = m.group(2).matches("Y") ? "YES" : "NO";
m.appendReplacement(sb, m.group(1) + repl + m.group(3));
}
m.appendTail(sb);
System.out.println(sb); // replaced string
You are checking the literal string "$2" to see if it matches "Y". This will never happen.
I have a set of strings, which I cycle through, checking those against the following set of regex, to try and separate the first small section from the rest of the string. The regex works in almost all cases, but unfortunately I have no idea why it fails occasionally. I’ve been using Pattern Matcher to print out the string, if the pattern is found.
Two example working strings:
98. SORGHUM Moench - Millets Annuals or rhizomatous perennials; inflorescence …
99. MISCANTHUS Andersson - Silver-grasses Rhizomatous perennials; inflorescence …
Two example failed strings:
100. ZEA L. - Maize Annuals; male and female inflorescences separate, the …
26. POA L. (Parodiochloa C.E. Hubb.) - Meadow-grasses Annuals or perennials with or without stolons or rhizomes; sheaths overlapping or some …
Regex’s used so far:
Pattern endOfGenus = Pattern.compile("(?<=(^\\d+\\. " + genusNames[l].toUpperCase() + "))");
Pattern endOfGenusTwo = Pattern.compile("(?<=(^\\d+" + genusNames[l].toUpperCase() + "))");
Pattern endOfGenusThree = Pattern.compile("(?<=(\\d+\\. " + genusNames[l] + "))");
Pattern endOfGenusFour = Pattern.compile("(?<=(\\d+" + genusNames[l] + "))");
Pattern endOfGenusFive = Pattern.compile("(?<=(\\. " + genusNames[l] + "))");
The first of these is the one thats producing the reliable results so far.
Example Code
Pattern endOfGenus = Pattern.compile("(?<=(^\\d+\\. " + genusNames[l].toUpperCase() + "))");
Matcher endOfGenusFinder = endOfGenus.matcher(descriptionPartBits[b]);
if (endOfGenusFinder.find()) {
System.out.print(descriptionPartBits[b] + ":- ");
System.out.print(genusNames[l] + "\n");
String[] genusNameBits = descriptionPartBits[b].split("(?<=(^\\d+\\. " + genusNames[l].toUpperCase() + "))");
}
Desired Output. This is what is produced by strings that work. Strings that don't work simply don't appear in the output:
98. SORGHUM Moench - Millets Annuals or rhizomatous perennials:- Sorghum
99. MISCANTHUS Andersson - Silver-grasses Rhizomatous perennials:- Miscanthus
From regex tutorial:
Lookahead and lookbehind, collectively called "lookaround", are
zero-length assertions just like the start and end of line, and start
and end of word anchors explained earlier in this tutorial.
Lookahead and lookbehind only return true or false.
So I changed your code example:
Pattern endOfGenus = Pattern.compile("(?<=(^\\d+\\. ZEA L))(.+)$");
// Matcher matcher = endOfGenus.matcher("98. SORGHUM Moench - Millets Annuals or rhizomatous perennials; inflorescence …");
Matcher matcher = endOfGenus.matcher("100. ZEA L. - Maize Annuals; male and female inflorescences separate, the …");
while (matcher.find()) {
String group1 = matcher.group(1);
String group2 = matcher.group(2);
System.out.println("group1=" + group1);
System.out.println("group2=" + group2);
}
Group 1 is matched by (^\\d+\\. ZEA L). Group 2 is matched by (.+).