13

I was wondering if Java had an equivalent to C#’s named pattern matching. For example, in C# I can do something like this:

var pattern = @";(?<foo>\d{6});(?<bar>\d{6});";
var regex = new Regex(pattern , RegexOptions.None);
var match = regex.Match(";123456;123456;");

var foo = match.Groups["foo"].Success ? match.Groups["foo"].Value : null;
var bar = match.Groups["bar"].Success ? match.Groups["bar"].Value : null;

This just seems like a clean way to grab groups. Can Java do something similar, or do I need to grab groups based on index position?

String foo = matcher.group(0);
0

3 Answers 3

20

This is supported starting in Java 7. Your C# code can be translated to something like this:

String pattern = ";(?<foo>\\d{6});(?<bar>\\d{6});";
Pattern regex = Pattern.compile(pattern);
Matcher matcher = regex.matcher(";123456;123456;");
boolean success = matcher.find();

String foo = success ? matcher.group("foo") : null;
String bar = success ? matcher.group("bar") : null;

You have to create a Matcher object which doesn't actually perform the regex test until you call find().

(I used find() because it can find a match anywhere in the input string, like the Regex.Match() method. The .matches() method only returns true if the regex matches the entire input string.)

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the fast reply. Unfortunately, we are still using Java 6. Maybe I'll just create an enum: String foo = matcher.group(MyGroups.FOO);
Check out the named-regexp project. Its specific purpose is to provide a way to handle named groups pre-Java7.
The updated fork of named-regexp is preferred.
Note that named groups will only work after calling matcher.matches()
@bcoughlan Ah, right you are. Thanks for pointing it out. I updated the answer to include this, though I used Matcher#find() because it matches C#'s Regex#Match() method more similarly than Matcher#matches().
2

Java v1.7 now supports Perl-standard named groups like (?<name>...) and \k<name> in patterns.

You cannot have duplicate group names in the same pattern, which can be annoying in very complex cases where you are building up larger patterns out of smaller pieces out of your control. It also lacks relative indexing.

However, it should be enough for such simple things as you appear to be writing.

Comments

-2

I believe you need import

org.apache.commons.lang3.StringUtils;

for this

 private Boolean validateEmail(String email)
    {
        return email.matches("^[-!#$%&'*+/0-9=?A-Z^_a-z{|}~](\\.?[-!#$%&'*+/0-9=?A-Z^_a-z{|}~])*@[a-zA-Z](-?[a-zA-Z0-9])*(\\.[a-zA-Z](-?[a-zA-Z0-9])*)+$");
    }

    private Boolean validateIP(String IP)
    {
        return IP.matches("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
    }

    private Boolean validateHostname(String Hostname)
    {
        return Hostname.matches("^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\\-]*[A-Za-z0-9])$");
    }

2 Comments

might have misunderstood the question. re-read it and now this doesnt seem like what u want. dont know what you mean by "grab groups"
Basically, I want a clean way to grab a matched pattern from the group array without using index numbers but a name instead.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.