2012-02-20 42 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