【问题标题】:A regex to return text from parsed word document从已解析的 word 文档中返回文本的正则表达式
【发布时间】:2016-09-23 09:55:33
【问题描述】:

我试图创建一个正则表达式来匹配我的 word 文档中的部分文本。 在 word 文档中,我有类似 {LigneDetails.Libelle} 的内容,所以当我用 java 处理这个文件时,它会生成如下:

<w:t>{</w:t>
         </w:r>
         <w:proofErr w:type="spellStart" />
         <w:r w:rsidRPr="009664EA">
            <w:t>SOCIETE.RaisonSociale</w:t>
         </w:r>
         <w:proofErr w:type="spellEnd" />
         <w:r w:rsidRPr="009664EA">
 <w:t>}</w:t>

所以我在这里使用这个正则表达式匹配曲括号之间的文本:\\{([^\\{])*\\},这将返回:

{</w:t>
         </w:r>
         <w:proofErr w:type="spellStart" />
         <w:r w:rsidRPr="009664EA">
            <w:t>SOCIETE.RaisonSociale</w:t>
         </w:r>
         <w:proofErr w:type="spellEnd" />
         <w:r w:rsidRPr="009664EA">
            <w:t>}

现在在我的 word 文档中我有这样的内容:{LigneDetails.Libelle:FAM:01}

这将生成:

<w:t>{</w:t>
    </w:r>
    <w:proofErr w:type="spellStart" />
    <w:r w:rsidRPr="002A51DD">
       <w:rPr>
          <w:sz w:val="14" />
          <w:szCs w:val="20" />
       </w:rPr>
       <w:t>LigneDetails.Libelle:FAM</w:t>
    </w:r>
    <w:proofErr w:type="spellEnd" />
    <w:r w:rsidRPr="002A51DD">
       <w:rPr>
          <w:sz w:val="14" />
          <w:szCs w:val="20" />
       </w:rPr>
       <w:t>:01}</w:t>

然后正则表达式将匹配该部分:

{</w:t>
                  </w:r>
                  <w:proofErr w:type="spellStart" />
                  <w:r w:rsidRPr="002A51DD">
                     <w:rPr>
                        <w:sz w:val="14" />
                        <w:szCs w:val="20" />
                     </w:rPr>
                     <w:t>LigneDetails.Quantite:FAM</w:t>
                  </w:r>
                  <w:proofErr w:type="spellEnd" />
                  <w:r w:rsidRPr="002A51DD">
                     <w:rPr>
                        <w:sz w:val="14" />
                        <w:szCs w:val="20" />
                     </w:rPr>
                     <w:t>:01}

到目前为止一切都很好。

现在我想匹配总是在: 之后的最后两个值,在我的情况下是FAM01,所以我希望这个正则表达式返回这两个值。

我该怎么做?

【问题讨论】:

  • 你的正则表达式是不是错了?您发布了 \{([^\{])*\}(删除了 Java 需要的双重转义),但您不应该改用 \{([^\}])*\},即匹配任何不是右花括号的东西吗?
  • 您的要求的问题是获得 正确 冒号 (:) reliably 非常困难(请参阅 teukkam 的评论,它可能试图明白了用正则表达式解析 XML/HTML 是一项艰巨的任务,如果标记的结构超出您的控制范围,肯定会失败 - XML/HTML 不是正则语言,因此正则表达式不太适合)。跨度>
  • @Thomas 我的正则表达式实际上正在工作并返回我想要的内容
  • @Thomas 那么如果我使用\{([^\}])*\} 来获取两个大括号之间的文本,然后创建一个符合我对返回字符串的要求的正则表达式呢?我注意到我想要的文本总是在&lt;w:t&gt;&lt;/w:t&gt; 之间,所以我的正则表达式将在上面返回的字符串中搜索&lt;w:t&gt;&lt;/w:t&gt; 之间的文本(在我的情况下,这将返回{,@ 987654340@ 和 :01}),然后它会查找 : 之后的文本,这将返回 FAM01,这有意义吗?

标签: java regex xml ms-word


【解决方案1】:

如果我们考虑到您当前的方法,您会留下一些 {...} 字符串,其中您可以删除 &lt;...&gt; 实体或文本或 { 在开头和 } 在结尾处用正则表达式。然后,您只需要抓取这些行并使用: 拆分,或者使用正则表达式来抓取: 符号之后的所有非空白字符。

Java 代码示例:

String str = "{</w:t>\n                  </w:r>\n                  <w:proofErr w:type=\"spellStart\" />\n                  <w:r w:rsidRPr=\"002A51DD\">\n                     <w:rPr>\n                        <w:sz w:val=\"14\" />\n                        <w:szCs w:val=\"20\" />\n                     </w:rPr>\n                     <w:t>LigneDetails.Quantite:FAM</w:t>\n                  </w:r>\n                  <w:proofErr w:type=\"spellEnd\" />\n                  <w:r w:rsidRPr=\"002A51DD\">\n                     <w:rPr>\n                        <w:sz w:val=\"14\" />\n                        <w:szCs w:val=\"20\" />\n                     </w:rPr>\n                     <w:t>:01}"; 
str = str.replaceAll("<[^<]*?>|^\\{|\\}$", "");
String[] lines = str.split("\n");
List<String> lst = new ArrayList<>();
for (String s : lines) {
    if (s.contains(":"))
        lst.add(s.trim().split(":")[1]);
}
System.out.println(lst);

Java demo

或者带有 :(\S+) 正则表达式的版本从剥离的字符串内容中抓取 1+ 个非空白块:

str = str.replaceAll("<[^<]*?>|^\\{|\\}$", "");
Matcher m = Pattern.compile(":(\\S+)").matcher(str);
List<String> lst = new ArrayList<>();
while (m.find()) {
    lst.add(m.group(1));
}

another demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 2016-04-27
    • 2023-04-02
    相关资源
    最近更新 更多