Регулярное выражение слишком голоден - PullRequest
0 голосов
/ 20 февраля 2012

Я ищу регулярное выражение, но не могу найти.

Синтаксический анализ текстового файла, похожего на этот

    <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 голосов
/ 23 февраля 2012

Я решил это с помощью этого выражения: <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.replace. Все я используюдля того, чтобы иметь возможность рассчитать замену для каждой находки.

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 ...

0 голосов
/ 20 февраля 2012

Как указывает г-н Е., это вовсе не лучший способ чтения данных из файла XML. Не говоря уже о том, вдруг ли вам приходится иметь дело с вложенными элементами! Однако это будет соответствовать атрибуту имени propertyValue внутри ресурса.

<resource.+?<propertyValue name=(["'])([^"']*)\1.+?</resource>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...