当前位置: 首页 > 知识库问答 >
问题:

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

邵毅
2023-03-14

说,我有一个字符串:

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个答案

黄沈浪
2023-03-14

您可以使用内置功能来处理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通过文本(")选择节点。//div[text() = 'Content']",通过id、类或者其他属性进行选择非常容易。但是,如果您经常进行这种替换,编写一个泛型类来处理这种情况可能是一个好主意。

柯奕
2023-03-14

您绝对可以使用正则表达式做到这一点,尽管它可能不是最优雅的解决方案。以下是您可能使用的模式:

这是通过使用负向前看和负向后看来实现的。负面展望:(?!

因此,模式被打破了:

<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>");

 类似资料:
  • 我已经尝试遍历字符串并手动替换它们,但计数是关闭的。我也尝试过使用列表、数组、stringbuilder等,但我无法使其工作: 我觉得必须有一种简单的方法来用子字符串替换字符串中的单个字符,而不必进行所有这些迭代。我说错了吗?

  • 问题内容: 我正在尝试替换字符串中特定索引处的字符。 我正在做的是: 这给出了一个错误。有什么方法可以做到这一点? 问题答案: 字符串在Java中是不可变的。你不能更改它们。 你需要创建一个新字符串并替换字符。 或者,你可以使用StringBuilder:

  • 问题内容: 我们可以使用以下函数在MySQL中找到给定子字符串首次出现的索引。 它会显示指定子字符串的第一次出现,在此情况下为下划线。 我需要获取给定字符(或子字符串)的最后一次出现,类似于String类的Java 方法,但是我找不到MySQL中的任何内置函数。 在MySQL中是否有任何内置功能可实现此目的? 问题答案: @马克·B很近。在MySQL中,以下语句返回12: 预期可能使用该值,以下语

  • 问题内容: 我曾经在JavaScript中这样做: Swift没有此功能,如何做类似的事情? 问题答案: 编辑/更新: Xcode 11•Swift 5.1或更高版本 用法: 不区分大小写的样本 正则表达式样本

  • 问题内容: 我想使用函数替换多个字符串。 我目前有 但想有类似的东西 虽然那听起来不像是好的语法 正确的方法是什么?有点像如何在中进行操作\1以及\2如何将字段替换为某些搜索字符串 问题答案: 这是一个简短的示例,应该使用正则表达式来解决问题: 例如: ’() and –text–‘

  • 问题内容: 说我有一个文件,其中包含一些文本。其中包含子字符串,例如“ substr1”,“ substr2”,“ substr3”等。我需要将所有这些子字符串替换为其他文本,例如“ repl1”,“ repl2”,“ repl3”。在Python中,我将创建一个这样的字典: 并创建用’|’组合键的模式,然后替换为function。在Java中有类似的简单方法吗? 问题答案: 这是您的Python