从特定索引替换字符串中子字符串的上一个和下一个索引

时间:2017-04-18 16:47:38

标签: java string replace find substring

说,我有一个字符串:

String someString = "<html><body><div><div><div class="unknown"><b>Content</b></div></div></div></body></html>";

在此字符串中,“内容”的位置是已知的。

现在,我想将最内在的div转换为span标签。那么我想做什么:

someString.replacePreviousOccurrence(someString.indexOf("Content"), "<div ", "<span>");
someString.replaceNextOccurrence(someString.indexOf("Content"), "</div>", "</span>");

Java中有什么东西可以做到这一点吗?或者只是从指定的索引获取上一次和下一次出现的子串的索引?

编辑:忘了指定div有未知标签(可能有类和东西),中间可能有东西(比如示例中的标签)。

2 个答案:

答案 0 :(得分:1)

你绝对可以用正则表达式做到这一点,尽管它可能不是最优雅的解决方案。以下是您可能使用的模式:<div>(?!<div>).*(?<!<\/div>)<\/div>

这可以通过使用negative lookahead and negative lookbehind来实现。这里的否定前瞻:(?!<div>)说找到这种模式,其中"<div>"后面没有后面的负面看法:(?<!<\/div>)说找不到</div>前面的模式

所以模式细分了:

<div>   //matches <div>
    (?!<div>) //that isn't followed by <div>
           .* //followed by any character any number of times
    (?<!<\/div>) // Where the next match isn't preceded by <div>
<\/div>    //matches </div>

因此,对于此问题,您可以执行以下操作:

String str = "<html><body><div><div><div class="unknown"><b>Content</b></div></div></div></body></html>";
Pattern p = "<div>(?!<div>).*(?<!<\/div>)<\/div>";
Matcher m = p.matcher(str);
String output = m.replaceAll("<div>", "<span>").replaceAll("</div>", "</span>");

答案 1 :(得分:1)

您可以使用内置功能来处理xml。

然而,遗憾的是,这非常冗长,但仍有效。

 public static void replaceDivWithSpamByText() throws ParserConfigurationException, IOException, SAXException, XPathExpressionException, TransformerException {
        String html = "<html><body><div><div><div>Content</div></div></div></body></html>";
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)));

        XPathFactory xPathFactory = XPathFactory.newInstance();
        XPath xpath = xPathFactory.newXPath();
        Node contentNode = (Node) xpath.evaluate(".//div[text() = 'Content']", doc, XPathConstants.NODE);
        doc.renameNode(contentNode, null, "span");


        DOMSource domSource = new DOMSource(doc);
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.transform(domSource, result);

        System.out.println(writer.toString()); 
    }

请注意,在此示例中,我使用Xpath按文本选择节点(&#34; .// div [text()=&#39; Content&#39;]&#34;),按ID选择,类或其他属性非常容易。但如果你经常进行这种替换,写一个通用类来处理这个问题可能是一个好主意。