【问题标题】:Pattern java Finding out what part of OR matched模式java找出OR匹配的部分
【发布时间】:2013-06-27 05:07:17
【问题描述】:

我有以下模式:

Pattern TAG = Pattern.compile("(<[\\w]+]>)|(</[\\w]+]>)");

请注意 |在模式中。

我有一个方法可以用这个模式做一些处理

private String format(String s){
    Matcher m = TAG.matcher(s);
    StringBuffer sb = new StringBuffer();

    while(m.find()){
        //This is where I need to find out what part
        //of | (or) matched in the pattern
        // to perform additional processing


    }
    return sb.toString();
}

我想根据 OR 中匹配的部分执行不同的功能 正则表达式。我知道我可以将模式分解为 2 个不同的模式并在每个模式上进行匹配,但这不是我正在寻找的解决方案,因为我的实际正则表达式要复杂得多,如果我能做到的话,我想要完成的功能效果最好它在一个循环和正则表达式中。所以我的问题是:

在 java 中有没有办法找出 OR 的哪一部分在正则表达式中匹配?

编辑 我也知道 m.group() 功能。它不适用于我的情况。下面的例子 打印出&lt;TAG&gt;&lt;/TAG&gt; 所以对于循环的第一次迭代它匹配&lt;[\\w]+&gt; 第二次迭代匹配&lt;/[\\w]+&gt;。但是我需要知道每次迭代中匹配的部分。

static Pattern u = Pattern.compile("<[\\w]+>|</[\\w]+>");

public static void main(String[] args) {
String xml = "<TAG>044453</TAG>";

Matcher m = u.matcher(xml);

while (m.find()) {
    System.out.println(m.group(0));
}
}

【问题讨论】:

  • 请注意您对group(0) 的使用与group(1) 或任何其他索引不同 - 第0 组是特殊的,因为它返回整个匹配项。添加括号可以让您根据需要访问匹配的较小部分。
  • 我在你的第一个模式中更正了/,因为你知道(&lt;[\\w]+]&gt;)|(&lt;/[\\w]+]&gt;)至少我没有误会你的意思:)

标签: java regex pattern-matching


【解决方案1】:

看看Matcher上的group()方法,你可以这样做:

if (m.group(1) != null) {
    // The first grouped parenthesized section matched
}
else if (m.group(2) != null) {
    // The second grouped parenthesized section matched
}

编辑:恢复为原始组号 - 不需要额外的括号。这应该适用于如下模式:

static Pattern TAG = Pattern.compile("(<[\\w]+>)|(</[\\w]+>)");

【讨论】:

  • 您上面的编辑有一个括号已被删除的示例。我将编辑此答案以提供更好的模式示例 - 我认为您需要在 | 周围加上括号。 group(0) 不是您应该使用的;它很特别,会返回整个匹配项。
【解决方案2】:

你应该通过分解出共同部分来重写你的模式:

xy|xz  => x(y|z)
xy|x   => xy?
yx|x   => y?x

然后,通过将y? 等有趣的部分放在括号中,您可以使用 group() 检查它是否已设置。

【讨论】:

    【解决方案3】:

    您不必将[]\\w 一起使用,因为它已经是一个类。此外,您可以用括号将 OR 部分的每个选项括起来,以便能够将它们用作组(如果找不到其中一个组,它将具有空引用)。所以你的代码可以是这样的:

    static Pattern u = Pattern.compile("(<\\w+>)|(</\\w+>)");
    
    public static void main(String[] args) {
        String xml = "<TAG>044453</TAG>";
    
        Matcher m = u.matcher(xml);
    
        while (m.find()) {
            if (m.group(1)!=null){// <- group 1 (<\\w+>)
                System.out.println("I found <...> tag: "+m.group(0));
            }else{ // if it wasn't (<\\w+>) then it means it had to be (</\\w+>) that was mathced 
                System.out.println("I found </...> tag: "+m.group(0));
            }
        }
    }
    

    您还可以将模式稍微更改为&lt;(/?)\\w+&gt;,使/ 成为可选部分并将其放在括号中(在这种情况下将使其成为第1 组)。这样,如果标签没有 /,那么组 1 将只包含空字符串 "",因此您可以将逻辑更改为类似

            if ("".equals(m.group(1))) {// 
                System.out.println("I found <...> tag: " + m.group(0));
            } else { 
                System.out.println("I found </...> tag: " + m.group(0));
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多