Java doesn't parse Regular Expressions in the same way as Python for a small set of cases. In this particular case the nested ['s were causing problems. In Python you don't need to escape any nested [ but you do need to do that in Java.

The original RegEx (for Python):

/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/([gim]+\b|\B)

The fixed RegEx (for Java and Python):

/(\\.|[^\[/\\\n]|\[(\\.|[^\]\\\n])*\])+/([gim]+\b|\B)
Answer from Vineet on Stack Overflow
Top answer
1 of 2
13

Java doesn't parse Regular Expressions in the same way as Python for a small set of cases. In this particular case the nested ['s were causing problems. In Python you don't need to escape any nested [ but you do need to do that in Java.

The original RegEx (for Python):

/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/([gim]+\b|\B)

The fixed RegEx (for Java and Python):

/(\\.|[^\[/\\\n]|\[(\\.|[^\]\\\n])*\])+/([gim]+\b|\B)
2 of 2
11

The obvious difference b/w Java and Python is that in Java you need to escape a lot of characters.

Moreover, you are probably running into a mismatch between the matching methods, not a difference in the actual regex notation:

Given the Java

String regex, input; // initialized to something
Matcher matcher = Pattern.compile( regex ).matcher( input );
  • Java's matcher.matches() (also Pattern.matches( regex, input )) matches the entire string. It has no direct equivalent in Python. The same result can be achieved by using re.match( regex, input ) with a regex that ends with $.
  • Java's matcher.find() and Python's re.search( regex, input ) match any part of the string.
  • Java's matcher.lookingAt() and Python's re.match( regex, input ) match the beginning of the string.

For more details also read Java's documentation of Matcher and compare to the Python documentation.

Since you said that isn't the problem, I decided to do a test: http://ideone.com/6w61T It looks like java is doing exactly what you need it to (group 0, the entire match, doesn't contain the ;). Your problem is elsewhere.

Top answer
1 of 2
4

As suggested by Wiktor in the comments, you could use (?U) to turn on the flag UNICODE_CHARACTER_CLASS. While this does allow matching äöa, this still doesn't match . That's because UNICODE_CHARACTER_CLASS with \w doesn't recognize ² as a valid alphanumeric character. As a replacement for \w, you can use [\pN\pL_]. This matches Unicode numbers \pN and Unicode letters \pL (plus _). The \pN Unicode character class includes the \pNo character class, which includes the Latin 1 Supplement - Latin-1 punctuation and symbols character class (it includes ²³¹). Alternatively, you could just add the \pNo Unicode character class to a character class with \w. This means the following regular expressions correctly match your strings:

[\pN\pL_]{2,}         # Matches any Unicode number or letter, and underscore
(?U)[\w\pNo]{2,}      # Uses UNICODE_CHARACTER_CLASS so that \w matches Unicode.
                      # Adds \pNo to additionally match ²³¹

So why doesn't \w match ² in Java but it does in Python?


Java's interpretation

Looking at OpenJDK 8-b132's Pattern implementation, we get the following information (I removed information irrelevant to answering the question):

Unicode support

The following Predefined Character classes and POSIX character classes are in conformance with the recommendation of Annex C: Compatibility Properties of Unicode Regular Expression, when UNICODE_CHARACTER_CLASS flag is specified.

\w A word character: [\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p{IsJoin_Control}]

Great! Now we have a definition for \w when the (?U) flag is used. Plugging these Unicode character classes into this amazing tool will tell you exactly what each of these Unicode character classes match. Without making this post super long, I'll just go ahead and tell you that neither of the following classes matches ²:

  • \p{Alpha}
  • \p{gc=Mn}
  • \p{gc=Me}
  • \p{gc=Mc}
  • \p{Digit}
  • \p{gc=Pc}
  • \p{IsJoin_Control}

Python's interpretation

So why does Python match ²³¹ when the u flag is used in conjunction with \w? This one was very difficult to track down, but I went digging into Python's source code (I used Python 3.6.5rc1 - 2018-03-13). After removing a lot of the fluff for how this gets called, basically the following happens:

  • \w is defined as CATEGORY_UNI_WORD, which is then prefixed with SRE_. SRE_CATEGORY_UNI_WORD calls SRE_UNI_IS_WORD(ch)
  • SRE_UNI_IS_WORD is defined as (SRE_UNI_IS_ALNUM(ch) || (ch) == '_').
  • SRE_UNI_IS_ALNUM calls Py_UNICODE_ISALNUM, which is, in turn, defined as (Py_UNICODE_ISALPHA(ch) || Py_UNICODE_ISDECIMAL(ch) || Py_UNICODE_ISDIGIT(ch) || Py_UNICODE_ISNUMERIC(ch)).
  • The important one here is Py_UNICODE_ISDECIMAL(ch), defined as Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch).

Now, let's take a look at the method _PyUnicode_IsDecimalDigit(ch):

int _PyUnicode_IsDecimalDigit(Py_UCS4 ch)
{
    if (_PyUnicode_ToDecimalDigit(ch) < 0)
        return 0;
    return 1;
}

As we can see, this method returns 1 if _PyUnicode_ToDecimalDigit(ch) < 0. So what does _PyUnicode_ToDecimalDigit look like?

int _PyUnicode_ToDecimalDigit(Py_UCS4 ch)
{
    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);

    return (ctype->flags & DECIMAL_MASK) ? ctype->decimal : -1;
}

Great, so basically, if the character's UTF-32 encoded byte has the DECIMAL_MASK flag this will evaluate to true and a value greater than or equal to 0 will be returned.

UTF-32 encoded byte value for ² is 0x000000b2 and our flag DECIMAL_MASK is 0x02. 0x000000b2 & 0x02 evaluates to true and so ² is deemed to be a valid Unicode alphanumeric character in python, thus \w with u flag matches ².

2 of 2
0

There is one more step left: you need to specify that \w includes unicode characters too. Pattern.UNICODE_CHARACTER_CLASS for the rescue:

    Pattern regex = Pattern.compile("(?u)\\b\\w\\w+\\b", Pattern.UNICODE_CHARACTER_CLASS);
                                                   // ^^^^^^^^^^
    Matcher matcher = regex.matcher("this is the document.!? äöa m²");

    while(matcher.find()) {
        String match = matcher.group();
        System.out.println(match);
    }
Discussions

Java regex matcher not matching - Stack Overflow
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. ... Save this answer. ... Show activity on this post. If you using Java > 7. More on stackoverflow.com
🌐 stackoverflow.com
2023 Day 2 Part A [Java] regex pattern not matching
Just getting a matcher from a pattern is not sufficient to get groups. You need to call e.g. the matchers find() method to execute a search and fill the groups. More on reddit.com
🌐 r/adventofcode
5
2
December 3, 2023
Python regex not working like it should - Stack Overflow
I am quite new to python and I'm working on a task where I'm supposed to keep building on a regex and I have encountered a full stop. For some reason when adding the latter parts some of the regex... More on stackoverflow.com
🌐 stackoverflow.com
Simple java regex not matching - Stack Overflow
Regex matching is done using .find(): Copyfinal Matcher matcher = patt.matcher("a 18c1"); if (matcher.find()) System.out.println(matcher.group()); ... Ok, then i am trying to call patt.matcher("a 18c1").group() , it returning java.lang.IllegalStateException: No match found 2014-03-18T13:15... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Baeldung
baeldung.com › home › java › core java › a guide to java regular expressions api
A Guide To Java Regular Expressions API | Baeldung
January 8, 2024 - In this tutorial, we’ll discuss the Java Regex API, and how we can use regular expressions in the Java programming language. In the world of regular expressions, there are many different flavors to choose from, such as grep, Perl, Python, PHP, awk, and much more. This means that a regular expression that works in one programming language, may not work in another.
🌐
Reddit
reddit.com › r/adventofcode › 2023 day 2 part a [java] regex pattern not matching
r/adventofcode on Reddit: 2023 Day 2 Part A [Java] regex pattern not matching
December 3, 2023 -

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;
    }

}
🌐
DevBolt
devbolt.dev › blog › fix-regex-errors
Regex Errors: Why Your Pattern Isn't Matching and How to Fix It | DevBolt
March 19, 2026 - ... A regex that works in one language may break in another because of how the host language handles string escaping. In Java, you must double-escape backslashes: "\\d+" to get the regex \d+. In Python, raw strings (r"\d+") avoid this problem.
Find elsewhere
🌐
Stack Overflow
stackoverflow.com › questions › 22480437
Simple java regex not matching - Stack Overflow
my regex returning false, cant understand why. Pattern patt = Pattern.compile("\\d+"); patt.matcher("a 18c1").matches(); //returning false Also I tried [0-9]+ , (\\d+), ([0-9]+), they didnt work t...
🌐
Reddit
reddit.com › r/learnpython › regex not matching despite successful tests
r/learnpython on Reddit: Regex not matching despite successful tests
August 4, 2021 -

I'm stumped with a regex problem.

I've tested this regex on multiple test sites (pythex.org and regex101.com), and all of them show that the regex is good. However, when Python runs the test, my match object (m) is None.

Regex: (.{0,25}\b)(?:humans|human)(\b.{0,25})

Text to search: Additional text Additional text Additional text Additional text This is a test - Testing response to the word human nested inside a paragraph with at least 25 characters on either side of the trigger word Additional text Additional text Additional text

Actual relevant code:

m = re.search("(.{0,25}\b)(?:humans|human)(\b.{0,25})", comment.body, re.IGNORECASE)
print(m)
if m:
	#stuff that doesn't happen because m = None

And when I run it, I get "None" in my output.

I even force updated all my libs. I don't know why this is coming up empty.

And yes comment.body is not blank (and PRAW is up to date)

🌐
Devwithus
devwithus.com › regex-not-match-java
Regex Not Match String In Java | devwithus.com
March 13, 2023 - Typically, we can use a negative lookahead to create a regex that does not match a specific word. Simply put, a negative lookahead is a special construct that matches a pattern only if it is not followed by another one.
🌐
NTU Singapore
www3.ntu.edu.sg › home › ehchua › programming › howto › Regexe.html
Regular Expression (Regex) Tutorial
Take note that in many programming languages (C, Java, Python), backslash (\) is also used for escape sequences in string, e.g., "\n" for newline, "\t" for tab, and you also need to write "\\" for \. Consequently, to write regex pattern \\ (which matches one \) in these languages, you need to write "\\\\" (two levels of escape!!!).
🌐
Google
developers.google.com › google for education › python › python regular expressions
Python Regular Expressions | Python Education | Google for Developers
Then the if-statement tests the ... did not succeed, and there is no matching text. The 'r' at the start of the pattern string designates a python "raw" string which passes through backslashes without change which is very handy for regular expressions (Java needs this ...
🌐
Java Code Geeks
javacodegeeks.com › home › web development › python
Python Regular Expressions - Java Code Geeks
March 18, 2020 - Since version 3.3, Python provides good support for Unicode regex pattern matching. As mentioned above, the \uFFFF syntax must be used.