使用正则表达式删除MS Word链接

时间:2015-08-26 11:53:16

标签: java regex

我正在解析MS Word文档并使用Apache POI获取文本。

对于看起来像这样的段落:

  

最受欢迎的水果是苹果和香蕉(请参阅下面的“Common fruits”和“Detailed botanic descriptions”小节)。

我得到一个看起来像这样的字符串:

The most popular fruits were apples and bananas (see section ‘\u0013 HYPERLINK \\l "_Common_fruit_types\" \u0001\u0014Common fruits\u0015’ and subsection ‘\u0013 HYPERLINK \\l \"_Botanic_description\" \u0001\u0014Detailed botanic descriptions\u0015’ below).

有不同类型的标签或关键字使用" PAGEREF"而不是" HYPERLINK",但似乎他们总是遵循模式\u0013 TAGWORD {String1} \u0001\u0014{String2}\u0015

所以我想要删除除{String2}之外的所有内容。到目前为止,我已经完成了:

  1. RegEx模式\u0013(.*?)\u0014 - 结果:{String2}\u0015(从我无法找到的SO页面获取此信息)

  2. RegEx模式\\[A-Za-z0-9]+删除最终\u0015 - 没有任何反应。我想表达的是,删除单词(包含字符和数字),包括它后面的反斜杠。还尝试了\\\\[A-Za-z0-9]+,结果相同。

  3. RegEx模式\u0013(.*?)u0015删除整个链接结构

  4. 由于\u0013(.*?)\u0014(.*?)\u0015执行相同操作(全部删除),我尝试了\u0013(.*?)\u0014[^(.*?)]\u0015,但它什么也没做。

  5. 替代方案: while循环

    boolean textWasChanged = true;
    while (textWasChanged) {
        int idx1 = text.indexOf("\u0013");
        int idx2 = text.indexOf("\u0014", idx1);
        if (idx1 > -1 && idx2 > -1 && text.replace(text.substring(idx1, idx2+1), "").length() < text.length()) {
            textWasChanged = true;
            text = text.replace(text.substring(idx1, idx2+1), "");
        } else {
            textWasChanged = false;
        }
    
    }
    text = text.replaceAll("\u0015", "");
    

    手动删除有效,但我想知道它是否可以简化为单行或其他内容。

    或更具体:

    1. 如何编写仅保留{String2}的正则表达式模式?从正则表达式手册,它看起来是可能的。我无法绕过它。
    2. 我在第2步和/或第4步中的错误在哪里?我只是否定了(.*?)部分,那是我想要保留的部分。但我显然不了解正则表达式。

1 个答案:

答案 0 :(得分:1)

您可以使用以下Pattern替换您的实体:

String raw = "The most popular fruits were apples and bananas "
        + "(see section ‘\\u0013 HYPERLINK \\l \"_Common_fruit_types\\\" "
        + "\\u0001\\u0014Common fruits\\u0015’ and subsection ‘\\u0013 HYPERLINK \\l"
        + "\\\"_Botanic_description\\\" "
        + "\\u0001\\u0014Detailed botanic descriptions\\u0015’ below).";

// test
System.out.printf("Raw string: %s%n%n", raw);
//                           | escaped back slash
//                           | | escaped unicode point
//                           | |      | any 1+ character, reluctant
//                           | |      |  | escaped \ and unicode point
//                           | |      |  |        | group 1: your goal
//                           | |      |  |        |    | escaped final \ + unicode point
Pattern p = Pattern.compile("\\\\u0013.+?\\\\u0014(.+?)\\\\u0015");
Matcher m = p.matcher(raw);
while (m.find()) {
    System.out.printf("Found: %s%n", m.group(1));
}
System.out.println();

// actual replacement
System.out.printf(
    "Replaced: %s%n", 
    raw.replaceAll("\\\\u0013.+?\\\\u0014(.+?)\\\\u0015", "$1")
);

输出(为了清晰起见,人工添加了换行符)

Raw string: The most popular fruits were apples and bananas (see section 
‘\u0013 HYPERLINK \l "_Common_fruit_types\" \u0001\u0014Common fruits\u0015’ 
and subsection ‘\u0013 HYPERLINK \l\"_Botanic_description\" 
\u0001\u0014Detailed botanic descriptions\u0015’ below).

Found: Common fruits
Found: Detailed botanic descriptions

Replaced: The most popular fruits were apples and bananas 
(see section ‘Common fruits’ and subsection ‘Detailed botanic descriptions’ below).