2012-06-22 1 views
11

Мне было интересно, если бы у Java был эквивалент сопоставления с образцом C#. Например, в C# я могу сделать что-то вроде этого:Поддержка Java для "(? <name> pattern)" в шаблонах

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; 

Это только кажется, как чистый способ, чтобы захватить группы. Может ли Java сделать что-то подобное или мне нужно захватить группы на основе позиции индекса?

String foo = matcher.group(0); 
+0

Один из самых раздражающих вещей о java = \ – Falmarri

ответ

16

Это поддерживается, начиная с Java 7. Ваш C# код может быть переведен на что-то вроде этого:

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; 

Вы должны создать Matcher объект, который на самом деле не выполнять проверку регулярных выражений, пока вы не вызовете find().

(я использовал find(), потому что он может найти матч в любом месте строки ввода, как метод Regex.Match(). Метод .matches() только возвращает истину, если регулярное выражение соответствует всей введенной строке.)

+1

Спасибо за быстрый ответ. К сожалению, мы все еще используем Java 6. Возможно, я просто создам перечисление: String foo = matcher.group (MyGroups.FOO); – aelstonjones

+1

Проверьте проект [named-regexp] (http://code.google.com/p/named-regexp/). Его конкретная цель - предоставить способ обработки названных групп pre-Java7. – matts

+1

Предпочитается обновленная версия ['named-regexp'] (http://tony19.github.io/named-regexp). – user46874

-2

Я считаю, что вам нужно импортировать

org.apache.commons.lang3.StringUtils;

для этого

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])$"); 
    } 
+0

, возможно, неправильно понял вопрос. перечитайте его, и теперь это не похоже на то, что вам нужно. не знаю, что вы подразумеваете под «группами захвата» –

+0

В принципе, я хочу, чтобы чистый способ захватить сопоставленный шаблон из массива групп без использования индексных номеров, но вместо имени. – aelstonjones

2

Java v1.7 прямо сейчас поддерживает Perl-стандартные именованные группы, такие как (?<name>...) и \k<name> в шаблонах.

У вас не может быть дублированных имен групп в одном шаблоне, что может раздражать в очень сложных случаях, когда вы создаете более крупные шаблоны из меньших частей из своего контроля. В нем также отсутствует относительная индексация.

Однако этого должно быть достаточно для таких простых вещей, как вы, кажется, пишете.