3

我有模式“abc|de.|ghi”和“def”的输入。如何找到匹配“def”的模式部分?所以,在这个例子中,我想要的结果是“de.”。不是“def”,这是我使用组和开始/结束方法所能得到的。

在代码中:

Pattern p = Pattern.compile("abc|de.|ghi");
Matcher m = p.matcher("def");
if(matcher.find()) {
    // Here I want to get the String "de." somehow
}
4

3 回答 3

3

这有点绕,但你可以用捕获组做你想做的事:

Pattern p = Pattern.compile("(abc)|(de.)|(ghi)");
Matcher m = p.matcher("def");
if(m.find()) {
    if (m.group(1) != null)
        System.out.println("Matched \"abc\"");
    if (m.group(2) != null)
        System.out.println("Matched \"de.\"");
    if (m.group(3) != null)
        System.out.println("Matched \"ghi\"");
}
于 2013-07-05T03:37:03.130 回答
1

所以,你想返回与输入匹配的正则表达式。我猜在 Pattern 或 Matcher 类中没有这样的方法来返回由 or 分隔的确切模式

所以,你可以这样做

public static String getMatchedRegexPattern(String inputRegex,String input) throws Exception
{
    if(Pattern.compile("(?<!\\\\)([\\(\\)\\[\\]])").matcher(inputRegex).find())throw new Exception("Groups,brackets not supported");
    for(String regex:inputRegex.split("(?<!\\\\)\\|"))//split only if | is not escaped
    {
    if(Pattern.compile(regex).matcher(input).matches())
        return regex;
    }
    return "";
}

你可以称之为

getMatchedRegexPattern("abc|de.|ghi","def");
于 2013-07-05T03:23:02.930 回答
1

Pattern在标准库中没有简单的方法可以做到这一点。

源代码Pattern使用递归下降解析器来创建一个对象树Node,每个对象都支持一个match()方法。例如,要评估|,在第 4107 行有一个Branch子类,它存储了可能的备选方案列表。它的match()方法尝试每个备选方案,true如果其中任何一个备选方案匹配且后继节点匹配,则返回。否则返回false

通过在解析树中插入特殊GroupHeadGroupTail节点来保存组,将每个组的开始和结束位置保存到Pattern类的私有变量中。

要找出模式的哪些部分导致匹配,节点对象需要知道导致它们被创建的模式部分。解析器根本不会将该信息存储在它创建的节点中。原始模式存储在temp数组中,递归下降解析器在解析时保留数组的cursor索引temp。从第 1567 行开始定义的解析器辅助方法(如peek()and accept())只是cursor根据需要递增。创建节点时, 的值cursor不会存储在任何地方。但是该值对于重建模式的哪些部分对应于匹配是必要的。

为什么Pattern不保存此信息是可以理解的:它会减慢所有正则表达式的计算速度,但几乎不会使用附加功能。

一种可能性是创建一个修改版本,该版本进行Pattern适当的簿记以将匹配追溯到它们来自的模式部分。为了存储每个节点对应的模式的哪一部分,您可以让构造函数存储该字段Node()的副本。cursor但是为了使用该数据来查找模式的哪些部分匹配,您需要更新每个Node子类的match()方法以根据…的每个子类的语义来存储范围Node

祝你好运!

于 2013-07-05T07:10:20.403 回答