Matcher.matchesreturnstrueonly if the ENTIRE region matches the pattern.For the output you are looking for, use
Matcher.findinstead
Explanation of each case:
Pattern p = Pattern.compile("[^A-Z]+");
Matcher matcher = p.matcher("GETs");
if (matcher.matches()) {
Fails because the ENTIRE region 'GETs' isn't lowercase
Pattern p = Pattern.compile("[A-Z]+");
Matcher matcher = p.matcher("GETs");
if (matcher.matches()) {
This fails because the ENTIRE region 'GETs' isn't uppercase
Pattern p = Pattern.compile("[A-Z]+");
Matcher matcher = p.matcher("GET");
if (matcher.matches()) {
The ENTIRE region 'GET' is uppercase, the pattern matches.
Matcher.matchesreturnstrueonly if the ENTIRE region matches the pattern.For the output you are looking for, use
Matcher.findinstead
Explanation of each case:
Pattern p = Pattern.compile("[^A-Z]+");
Matcher matcher = p.matcher("GETs");
if (matcher.matches()) {
Fails because the ENTIRE region 'GETs' isn't lowercase
Pattern p = Pattern.compile("[A-Z]+");
Matcher matcher = p.matcher("GETs");
if (matcher.matches()) {
This fails because the ENTIRE region 'GETs' isn't uppercase
Pattern p = Pattern.compile("[A-Z]+");
Matcher matcher = p.matcher("GET");
if (matcher.matches()) {
The ENTIRE region 'GET' is uppercase, the pattern matches.
You're very first regex asks to match any character that is not in an uppercase range of A-Z. The match is on the lowercase "s" in GETs.
First time posting here, let me know if I need to edit post to conform to any rules. My issue is that I'm trying to match regex pattern to separate out the number of cubes drawn and its color but my Matcher object seems to not be returning any matches so it's throwing a no match found exception when I try to call digitMatcher.group(). I have tested my regex pattern on sites like regexr and it seems to pass there but it's not working for some reason here. I use the same type of regex on day one and it work there so I'm not sure where my regex pattern is failing here. I'm talking about specifically in my isGameValid() method where I create a matcher base on a pattern I made above. Through debugging I know that I separated the string color pairing correctly and that my Matcher object has the correct regex pattern, it's just not matching for some reason. Any help would be appreciated. Code below:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.lang.Integer.parseInt;
import static java.lang.Integer.sum;
public class dayTwoA {
public static final Map<String, Integer> map = Map.of( // Mapping of digits to their letter spelling.
"red", 12,
"green", 13,
"blue", 14
);
public static final Pattern colorPattern = Pattern.compile("blue|green|red");
public static final Pattern digitPattern = Pattern.compile("[0-9]|[0-9][0-9]");
public static int gameID = 0;
public static void main(String[] args) throws FileNotFoundException {
int sumGamesID = 0; // Sum of all the game ID.
// Create a scanner to get input from file.
Scanner inputFile = new Scanner(new File("src/dayTwoData.txt"));
// Parse file for data.
while (inputFile.hasNextLine()) {
String inputLine = inputFile.nextLine(); // Grab next line of input.
if (isGameValid(inputLine)) {
sumGamesID += gameID;
};
}
System.out.println("The sum of the ID of the games is " + sumGamesID);
}
private static boolean isGameValid(String inputLine) {
String gameDraws = inputLine.substring(inputLine.indexOf(":") + 1);
gameID++; // Increment game ID.
StringTokenizer separateDraw = new StringTokenizer(gameDraws, ";");
while (separateDraw.hasMoreTokens()) {
String draw = separateDraw.nextToken();
StringTokenizer numColor = new StringTokenizer(draw, ",");
while (numColor.hasMoreTokens()) {
String numColorPair = numColor.nextToken();
Matcher digitMatcher = digitPattern.matcher(numColorPair);
int numCubes = parseInt(digitMatcher.group());
Matcher colorMatcher = colorPattern.matcher(numColorPair);
String color = colorMatcher.group();
System.out.println(numCubes + "-" + colorMatcher.group());
if (numCubes > map.get(color)) {
return false;
}
System.out.println(numColorPair);
}
}
return true;
}
}Java Pattern not matching RegEx - Stack Overflow
Java regex matcher not matching - Stack Overflow
Java Regex not matching properly - Stack Overflow
Simple java regex not matching - Stack Overflow
Matcher.matches() matches the complete string. You can use Matcher.find to match the individual integers:
while (m.find()) {
System.out.println(m.group(1));
}
Matcher.matches tells you if your regex matches the entire string. Your string isn't all digits. It contains letters, dots, equal signs, and square brackets. So you matcher doesn't match.
You want Matcher.find(). That searches for partial matches. Matcher.group then allows you to retrieve the matched portion of the input string.
You first need to do
matcher.find()
to trigger the actual search. Usually like this:
Pattern pattern = Pattern.compile("(browse/)(.*)(\">)");
Matcher matcher = pattern.matcher(match);
if (matcher.find())
return matcher.group(1);
You should probably be using a different regex, though:
Pattern pattern = Pattern.compile("browse/([^<>\"]*)\">");
will be safer and more efficient (and provide the correct value in group number 1).
You have to call Matcher.find() or Matcher.matches() before you extract groups.
In your exact case you should call Matcher.find(), since your regex won't match against the entire input, which is what Matcher.matches() checks for.
Java's String.matches function matches the entire string, instead of just one part. That means, it is roughly equivalent to the regex ^[^=]=[^=]$, so both returns false. To build a regex working equivalent to yours, you should use:
str.matches("(?s).*[^=]=[^=].*")
(The (?s) ensures the . matches everything.)
Alternatively, you could build a Pattern and use Matcher for greater flexibility. This is what String.matches uses.
final Pattern p = Pattern.compile("[^=]=[^=]");
final Matcher m = p.matcher(str);
return m.find();
You must add either * or + to your regexp:
str.matches("[^=]+=[^=]+")
This is needed, because string.matches() is anchored by default. This is equivalent to ^[^=]+=[^=]+$ and means that it must match the whole string and not only a part of it.
There are two issues with your code
\bshould be\\bYou should be using
find()rather thanmatches(). The first will do a search on a given string and stops when it finds substring that matches the regex. Second will do a search on entire string. Because the provided regex doesn't match with the full string, thematches()does not work.
Simply fix your code on these two points, then it'll work. Tested myself.
Found answer using text2re.com
public String extractVal(String dataRaw) {
String re1=".*?"; // Non-greedy match on filler
String re2="(?:[a-z][a-z]+)"; // Uninteresting: word
String re3=".*?"; // Non-greedy match on filler
String re4="((?:[a-z][a-z]+))"; // Word 1
Pattern patt = Pattern.compile(re1+re2+re3+re4,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher matc = patt.matcher(dataRaw);
if (matc.find()) {
return matc.group(1);
}
return null;
}
Still unsure what i screwed up, though.
EDIT: better solution:
public String extractVal(String dataRaw) {
String test = ".+:\"(.+)\"";
Pattern patt = Pattern.compile(test,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher matc = patt.matcher(dataRaw);
if (matc.find()) {
return matc.group(1);
}
return null;
}
SOLVED: I have still no idea what was wrong but it is working now... Thanks to everyone.
Hello,
I am currently trying to match the content of a packet, unfortunately, the regex doesn't match. I tested it on regex101.com (https://regex101.com/r/AGUVr4/1/) and IntelliJ offers a tester as well, it confirmed it confirmed that it is working as well. However, when I run my code, it doesn't match.
^(.+)(Host: launcher2\\.robertsspaceindustries\\.com).+(User-Agent: libcurl-agent\\/[0-9]\\.[0-9]).+(Accept: application\\/json).+(Content-Type: application\\/json).+(Content-Length: [0-9]+)(.+)$
Code: https://hastebin.com/suloguxifa.java
Any help is welcome.
matches() means it should match completely, i.e. the whole string fits the RE. Your RE does not allow anything after the ')'. Try using find() instead matches().
Seems like you are attempting to match some sort of variable declaration in source code.
In your regex, you have this after the part that I imagine is meant to match "const (optionally) datatype":
"(const )?[a-zA-Z0-9\\*]*\\ "
Is the \\ prior to the space intentional? Do you mean to match a single \ ?
Here is the update you need to make to your code - the 2 regexes in the extractor method should be changed to
private static final Pattern THEOREM_REGEX = Pattern.compile(Pattern.quote("\\begin\\{theorem\\}") + "(.+?)" + Pattern.quote("\\end\\{theorem\\}"));
private static final Pattern PROOF_REGEX = Pattern.compile(Pattern.quote("\\begin\\{proof\\}") + "(.+?)" + Pattern.quote("\\end\\{proof\\}"));
The result will be "Hello, World!". See IDEONE demo.
The string you have is actually \begin\{theorem\} Hello, World! \end\{theorem\}. The literal backslashes in Java strings are doubled and when you need to match a literal backslash in Java with a regex, you need to use \\\\. To avoid the backslash hell, Pattern.quote can be of help that will tell the regex to treat all the subpattern inside it as a literal.
More details about Pattern.quote can be found in the documentation:
Returns a literal pattern
Stringfor the specifiedString.
This method produces aStringthat can be used to create aPatternthat would match the stringsas if it were a literal pattern.Metacharacters or escape sequences in the input sequence will be given no special meaning.
Your first regex needs to be:
Pattern THEOREM_REGEX = Pattern.compile("\\\\begin\\\\\\{theorem\\\\\\}(.+?)\\\\end\\\\\\{theorem\\\\\\}");
as you're trying to match a backslash that requires \\\\ in your regex.
Welcome to Java's misnamed .matches() method... It tries and matches ALL the input. Unfortunately, other languages have followed suit :(
If you want to see if the regex matches an input text, use a Pattern, a Matcher and the .find() method of the matcher:
Pattern p = Pattern.compile("[a-z]");
Matcher m = p.matcher(inputstring);
if (m.find())
// match
If what you want is indeed to see if an input only has lowercase letters, you can use .matches(), but you need to match one or more characters: append a + to your character class, as in [a-z]+. Or use ^[a-z]+$ and .find().
[a-z] matches a single char between a and z. So, if your string was just "d", for example, then it would have matched and been printed out.
You need to change your regex to [a-z]+ to match one or more chars.
by default Java sticks in the ^ and $ operators, so something like this should work:
public class PatternTest {
public static void main(String[] args) {
System.out.println("117_117_0009v0_172_5738_5740".matches("^([0-9_]+v._.).*$"));
}
}
returns:
true
Match content:
117_117_0009v0_1
This is the code I used to extract the match:
Pattern p = Pattern.compile("^([0-9_]+v._.).*$");
String str = "117_117_0009v0_172_5738_5740";
Matcher m = p.matcher(str);
if (m.matches())
{
System.out.println(m.group(1));
}
If you want to check if a string starts with the certain pattern you should use Matcher.lookingAt() method:
Pattern pattern = Pattern.compile("([0-9_]+v._.)");
Matcher matcher = pattern.matcher("117_117_0009v0_172_5738_5740");
if (matcher.lookingAt()) {
int groupCount = matcher.groupCount();
for (int i = 0; i <= groupCount; i++) {
System.out.println(i + " : " + matcher.group(i));
}
}
Javadoc:
boolean java.util.regex.Matcher.lookingAt()
Attempts to match the input sequence, starting at the beginning of the region, against the pattern. Like the matches method, this method always starts at the beginning of the region; unlike that method, it does not require that the entire region be matched. If the match succeeds then more information can be obtained via the start, end, and group methods.
You may add a |(.) alternative to your pattern (to match any char but a line break char) and check if Group 1 matched upon each match. If yes, output false, else, output true:
String argument = "#a1^b2";
Pattern pattern = Pattern.compile("[a-zA-Z]|[0-9]|\\s|(.)"); // or "[a-zA-Z0-9\\s]|(.)"
Matcher matcher = pattern.matcher(argument);
while(matcher.find()) { // find all matching characters
System.out.println(matcher.group(1) == null);
See the Java demo, output:
false
true
true
false
true
true
Note you do not need to use a Pattern.DOTALL here, because \s in your "whitelist" part of the pattern matches line breaks.
Why not simply removing all matching chars from your string, so you get only the non matching ones back:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexUtil {
public static void main(String[] args) {
String argument;
Pattern pattern;
Matcher matcher;
argument = "#a1^b2";
pattern = Pattern.compile("[a-zA-Z]|[0-9]|\\s");
matcher = pattern.matcher(argument);
// find all matching characters
while(matcher.find()) {
System.out.println(matcher.group());
argument = argument.replace(matcher.group(), "");
}
System.out.println("argument: " + argument);
}
}