正则表达式太饿了

时间:2012-02-20 11:07:03

标签: java regex

我正在寻找正则表达式,但找不到。

解析看起来像那样的文本文件

    <resource name="/_op_sox/Project/Default/ICDocumentation/Evaluation/Allianz/Allianz SE/Eval_01241.txt"
              inheritAcls="true">
        <bundle name="AZEvaluation">
            <property name="End Date">
            </property>
            <property name="Evaluation Type">
                <propertyValue name="RCSA"/>
            </property>
        </bundle>
    </resource>
    <resource name="/_op_sox/Project/Default/ICDocumentation/Evaluation/Allianz/Allianz SE/Eval_01481.txt"
              inheritAcls="true">
        <bundle name="AZEvaluation">
            <property name="End Date">
            </property>
            <property name="Evaluation Type">
                <propertyValue name="TRA"/>
            </property>
        </bundle>
    </resource>
   <resource name="/_op_sox/Project/Default/ICDocumentation/Evaluation/Allianz/Allianz SE/Eval_01362.txt"
              inheritAcls="true">
        <bundle name="AZEvaluation">
            <property name="End Date">
            </property>
            <property name="Evaluation Type">
                <propertyValue name="RCSA"/>
            </property>
        </bundle>
    </resource>

我当前的正则表达式匹配很多。

<resource.+?<propertyValue name="RCSA".+?</resource>

它匹配第一个资源标记和第二个+第三个。 有人可以改变它在第一个</resource>

时真正停止的正则表达式

我使用这个Java代码

Pattern.compile("<resource.+?<propertyValue name=\"RCSA\".+?</resource>",Pattern.MULTILINE | Pattern.DOTALL)

2 个答案:

答案 0 :(得分:0)

正如E先生所指出的,这根本不是从XML文件中读取数据的最佳方式。更不用说你是否突然不得不处理嵌套元素!但是,这将匹配资源中propertyValue的name属性。

<resource.+?<propertyValue name=(["'])([^"']*)\1.+?</resource>

答案 1 :(得分:0)

我用这个表达式解决了它:<resource(?:(?!<propertyValue).)+<propertyValue name="RCSA"(?:(?!<resource).)+</resource>但它会慢下来。 所以我看了一下Java可以做些什么,找到了一个简单快速的解决方案。

    Pattern p = Pattern.compile("<resource name=.+?</resource>",
            Pattern.MULTILINE | Pattern.DOTALL);
    String in = getStringFromFile(path, name, pre, count);
    System.out.println("Länge: " + in.length());
    Matcher m = p.matcher(in);
    StringBuffer sb = new StringBuffer();
    int c = 0;
    while (m.find()) {
        m.appendReplacement(sb, getReplacementStage1(m, c++));
    }
    m.appendTail(sb);
    writeStringToFile(path, name, pre, count, sb.toString());

首先,我使用更简单,更快速的RegEx,然后使用匹配器而不是使用String.replaceAll,我使用匹配器来计算每个查找的替换。

private static String getReplacementStage1(Matcher m, int c) {
    Pattern p1 = Pattern.compile(
            "<resource[^>]*?contentType=\"Evaluation\"", Pattern.MULTILINE
                    | Pattern.DOTALL);
    Matcher m1 = p1.matcher(m.group());
    if (!m1.find()) {
        // remove
        return "";
    }
    Pattern p2 = Pattern.compile("<propertyValue name=\"(?:RCSA|TRA)\"",
            Pattern.MULTILINE | Pattern.DOTALL);
    Matcher m2 = p2.matcher(m.group());
    if (m2.find()) {
        // remove
        return "";
    }
    // no change, return the group
    return m.group();
}

所以可能这个解决方案可以帮助有类似问题的人,不喜欢/需要XML解析器......