获取包含与模式匹配的文本的对象列表

Flo*_*oal 6 java regex apache-poi

我目前正在使用API​​ Apache POI,我正在尝试用它来编辑Word文档(*.docx).文档由段落(在XWPFParagraph对象中)组成,段落包含嵌入在'runs'(XWPFRun)中的文本.一个段落可以有很多次运行(取决于文本属性,但它有时是随机的).在我的文档中,我可以有特定的标签,我需要用数据替换(我的所有标签都遵循这种模式<#TAG_NAME#>)

因此,例如,如果我处理包含文本的段落Some text with a tag <#SOMETAG#>,我可以得到类似的东西

XWPFParagraph paragraph = ... // Get a paragraph from the document
System.out.println(paragraph.getText());
// Prints: Some text with a tag <#SOMETAG#>
Run Code Online (Sandbox Code Playgroud)

但是,如果我想编辑该段落的文本,我需要处理运行并且运行次数不固定.因此,如果我用该代码显示运行的内容:

System.out.println("Number of runs: " + paragraph.getRuns().size());
for (XWPFRun run : paragraph.getRuns()) {
    System.out.println(run.text());
}
Run Code Online (Sandbox Code Playgroud)

有时它可能是这样的:

// Output:
// Number of runs: 1
// Some text with a tag <#SOMETAG#>
Run Code Online (Sandbox Code Playgroud)

和其他时间一样

// Output:
// Number of runs: 4
// Some text with a tag 
// <#
// SOMETAG
// #>
Run Code Online (Sandbox Code Playgroud)

我需要做的是获得包含标记开头的第一次运行以及包含标记其余部分的以下运行的索引(如果标记在许多运行中被分割).我已经设法获得该算法的第一个版本,但它只有在tag(<#)的开头和tag()的结尾#>没有划分时才有效.这就是我已经做过的事情.

所以我想获得一个算法能够管理这一问题,如果可能的话把它与任何特定的标签(不一定是工作<#和#>,这样我就可以像这样的东西代替{{{,这}}}).

对不起,如果我的英语不完美,请不要犹豫,让我澄清你想要的任何一点.

Flo*_*oal 2

最后我自己找到了答案,我完全改变了我对原始算法的思考方式(我对其进行了评论,因此它可能会帮助那些可能处于与我相同情况的人)

// Before using the function, I'm sure that:
// paragraph.getText().contains(surroundedTag) == true
private void editParagraphWithData(XWPFParagraph paragraph, String surroundedTag, String replacement) {
    List<Integer> runsToRemove = new LinkedList<Integer>();
    StringBuilder tmpText = new StringBuilder();
    int runCursor = 0;

    // Processing (in normal order) the all runs until I found my surroundedTag
    while (!tmpText.toString().contains(surroundedTag)) {
        tmpText.append(paragraph.getRuns().get(runCursor).text());
        runsToRemove.add(runCursor);
        runCursor++;
    }

    tmpText = new StringBuilder();
    // Processing back (in reverse order) to only keep the runs I need to edit/remove
    while (!tmpText.toString().contains(surroundedTag)) {
        runCursor--;
        tmpText.insert(0, paragraph.getRuns().get(runCursor).text());
    }

    // Edit the first run of the tag
    XWPFRun runToEdit = paragraph.getRuns().get(runCursor);
    runToEdit.setText(tmpText.toString().replaceAll(surroundedTag, replacement), 0);

    // Forget the runs I don't to remove
    while (runCursor >= 0) {
        runsToRemove.remove(0);
        runCursor--;
    }

    // Remove the unused runs
    Collections.reverse(runsToRemove);
    for (Integer runToRemove : runsToRemove) {
        paragraph.removeRun(runToRemove);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以现在我正在处理该段落的所有运行,直到找到包围的标签,然后我正在处理该段落以忽略第一次运行(如果我不需要编辑它们)。