2012-02-20 26 views
0

我正在寻找一个正则表达式,但无法找到。正则表达式太饿了

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

<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) 
+13

使用XML解析器。 – YXD 2012-02-20 11:09:13

+0

简单的问题 - 为什么你不使用XML工具?正则表达式不是优于XML或HTML – SergeS 2012-02-20 11:09:28

+0

为什么不使用Jsoup?找到第一个'resource'元素是很简单的。 – bdares 2012-02-20 11:09:36

回答

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()); 

所以首先我用一个更容易和更快的正则表达式,然后而是采用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解析器...

0

为E先生所指出的,这是不是最好的方式,在阅读从一个XML文件中的数据的正则表达式所有。更何况,如果你突然不得不处理嵌套元素!但是,这将与资源内的propertyValue的name属性匹配。

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

我不需要名称属性的内容。如果属性值的name属性是RCSA,我想要替换整个资源元素。 – Nabor 2012-02-20 11:19:28

+1

啊,我看到,无论如何,考虑使用XML解析器并遍历子节点。即使你以这种方式工作,它也不是一个长期的解决方案,并且最终注定会在某些XML文件上失败。 – 2012-02-20 11:26:42

+0

XML文件大小为200MB。它有很多不同的标签,我在这里没有提到。因此,使用5种不同的正则表达式来减少文件或更改一些内容。编写一个XML解析需要几个小时... – Nabor 2012-02-20 11:31:13