Java对模式中“(?<name>pattern)”的支持[重复]

Posted

技术标签:

【中文标题】Java对模式中“(?<name>pattern)”的支持[重复]【英文标题】:Java support for "(?<name>pattern)" in patterns [duplicate] 【发布时间】:2012-06-25 01:04:28 【问题描述】:

我想知道 Java 是否有与 C# 的命名模式匹配等价的功能。例如,在 C# 中,我可以这样做:

var pattern = @";(?<foo>\d6);(?<bar>\d6);";
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);

【问题讨论】:

【参考方案1】:

从Java 7 开始支持此功能。你的 C# 代码可以翻译成这样的:

String pattern = ";(?<foo>\\d6);(?<bar>\\d6);";
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() 方法只有在正则表达式匹配整个输入字符串时才返回 true。)

【讨论】:

感谢您的快速回复。不幸的是,我们仍在使用 Java 6。也许我会创建一个枚举:String foo = matcher.group(MyGroups.FOO); 查看named-regexp 项目。它的具体目的是提供一种在 Java7 之前处理命名组的方法。 首选named-regexp的更新fork。 请注意,命名组只有在调用matcher.matches()后才能工作 @bcoughlan 啊,没错。感谢您指出。我更新了答案以包含此内容,尽管我使用了 Matcher#find(),因为它与 C# 的 Regex#Match() 方法比 Matcher#matches() 更相似。【参考方案2】:

Java v1.7 现在支持 Perl 标准命名组,例如模式中的 (?&lt;name&gt;...)\k&lt;name&gt;

您不能在同一模式中拥有重复的组名,这在非常复杂的情况下可能会很烦人,因为您要从无法控制的较小部分构建较大的模式。它也缺乏相对索引。

但是,对于您所写的这些简单的事情来说,这应该足够了。

【讨论】:

【参考方案3】:

我相信你需要导入

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

【讨论】:

可能误解了这个问题。重新阅读它,现在这似乎不是你想要的。不知道你说的“抓包”是什么意思 基本上,我想要一种干净的方法来从组数组中获取匹配的模式,而不使用索引号而是使用名称。

以上是关于Java对模式中“(?<name>pattern)”的支持[重复]的主要内容,如果未能解决你的问题,请参考以下文章

java设计模式之命令模式以及在java中作用

java设计模式之代理模式:

Java代码实现设计模式之工厂模式

Java对观察者模式的支持

java 流程式代码适合啥设计模式

Java中的GOF23(23中设计模式)--------- 工厂模式(Factory)