【问题标题】:Get text between `<pre>` and `</pre>` into an ArrayList获取 `<pre>` 和 `</pre>` 之间的文本到 ArrayList
【发布时间】:2012-09-10 14:07:06
【问题描述】:

我需要从字符串中取出一些特定的文本并将其放入数组列表中,但我不知道从哪里开始。 字符串如下所示:

String exampleString = "some text I don't know <pre>the text I want to get</pre><pre>Some more text I want to get</pre> some text I don't know"

但问题是我不知道&lt;pre&gt; text &lt;/pre&gt; 有多少文本部分,甚至可能根本没有这些部分。

那么谁能告诉我如何获取&lt;pre&gt;&lt;/pre&gt; 之间的文本以及如何将它们放入arraylist。

非常感谢!

更新:我所知道的关于我所说的“一些我不知道的文本”的文本是它不包含 &lt;pre&gt;&lt;/pre&gt;

【问题讨论】:

  • 你试过正则表达式吗?类似&lt;pre&gt;(.+?)&lt;/pre&gt;?
  • 你要获取整个字符串还是在
    上拆分字符串?
  • @paul 不,你能再解释一下吗?
  • @Averroes 只要我得到&lt;pre&gt;&lt;/pre&gt; 之间的文本就可以了
  • 我不确定你想要什么,但我想摆脱
     标签,你可以试试 String myString = exampleString.replace("
    ", "") .replace("
    ", "")

标签: java android eclipse string arraylist


【解决方案1】:

假设没有嵌入标签,你可以这样做:

private List<String> getText(String text){

    List<String> result = new ArrayList<String>();

    String[] sections = text.split("<pre>");
    int i = 0;
    for (String s : sections) {
        i = s.indexOf("</pre>");
        if (i >= 0)          
           results.add(s.substring(0, i));        
    }  
    return result;
}

运行时的代码示例

说:

text = "test text here <pre> item one </pre> and then another item <pre> item 2 </pre> and then some stuff."

所以首先要说明的是:

String[] sections = text.split("<pre");

这定义了一个新的字符串数组,并将其分配给调用“text”的字符串拆分函数的结果

此函数将字符串分成由"&lt;pre&gt;" 分隔的部分,因此您得到:

sections[0] = "test text here" 
sections[1] = "item one </pre> and then another item"
sections[2] = "item 2 </pre> and then some stuff."

正如你所看到的,我们现在需要做的就是删除"&lt;/pre&gt;"之后的所有内容,这是下一个位的来源:

for (String s : sections)

是“for each”循环的开始,该循环将 String s 依次分配给数组部分的每个元素。

所以对于上面 3 个字符串中的每一个,我们都这样做:

 i = s.indexOf("</pre>");
    if (i >= 0)          
       results.add(s.substring(0, i));

因此,如果字符串包含&lt;/pre&gt;,则从开始到"&lt;/pre&gt;" 取一个子字符串并将其添加到我们的结果中。由于section[1] 和section[2] 包含它,它们最终会出现在结果中。

我希望这会有所帮助?


这是我如何实现 JavaJugglers 解决方案以避免使用 while (true):

private List<String> getText(String text){
    List<String> result = new ArrayList<String>();

    int indexStart = text.indexOf("<pre>");
    int indexEnd = text.indexOf("</pre>");
    while (indexStart >= 0 && indexEnd > indexStart) {
        result.add(text.substring(indexStart + 5, indexEnd));
        text = text.substring(indexEnd + 6);
        indexStart = text.indexOf("<pre>");
        indexEnd = text.indexOf("</pre>");
    }

    return result;
}

【讨论】:

  • 每种语法都是Java,使用迭代器对象。我认为是在 Java 5 中引入的。它只是意味着对于数组中的每个字符串,称为部分,设置 s 以引用该字符串并执行此代码。见:docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html
  • 好的,非常感谢您的两个解决方案,但是对于第二个解决方案,您不会陷入无限循环,因为 indexStart 和 indexEnd 不会更改,因为 exampleString 不会改变还是我错了?
  • 不,你是对的,那个代码是错误的,它应该是“text”而不是“exampleString”我会编辑。
  • 哦,我明白了,非常感谢您的耐心等待,第二个答案正是我想要的。非常感谢!!!
  • 我会在我的原始帖子中添加一个解释。
【解决方案2】:
try {
    Pattern pattern = Pattern.compile("<pre>(.+?)</pre>");
    Matcher matcher = pattern.matcher(yourText);

    while (matcher.find()) {
        //  matcher.group() will contain the match from the previous find() statement
    }
}
catch(Exception ex){}

已编辑:更正正则表达式语法

【讨论】:

  • 但是当有多个以&lt;pre&gt; 开头并以&lt;/pre&gt; 结尾的部分时,您该怎么做?
  • 这就是正则表达式的作用。 matcher.find() 将返回下一个匹配项。多次调用以查找所有匹配项。
  • 那么我必须在 yourText 中填写什么?
  • 哦,我想我明白了,是String exampleString = "some text I don't know &lt;pre&gt;the text I want to get&lt;/pre&gt;&lt;pre&gt;Some more text I want to get&lt;/pre&gt; some text I don't know"吗?
  • 是 - yourText 是您要搜索 &lt;pre&gt; 标签的文本
【解决方案3】:

如果您确定 HTML 格式正确,您可以从使用简单的String 方法开始:

String foo = "some text I don't know <pre>the text I want to get</pre><pre>Some more text I want to get</pre> some text I don't know";
int preStart = foo.indexOf("<pre>");
int preEnd = foo.indexOf("</pre>", preStart);

if (preStart > -1 && preEnd > preStart)
{
    String inBetweenTags = foo.substring(preStart + 5, preEnd);
    System.out.println(inBetweenTags);
}

http://ideone.com/OkE9B

否则使用 HTML 解析器。

【讨论】:

  • 但是当有多个带有&lt;pre&gt;&lt;/pre&gt;的文本部分时,这段代码会做什么?
  • 获取第一个这样的部分。
  • 即使 XML 格式正确但嵌入了
     元素,这也会出错,因为您最终会看到多个打开的标签,但从第一次关闭时就停止读取。
  • @GlenLamb 格式良好的 HTML != 格式良好的 XML。有效的 HTML 不能嵌套 &lt;pre&gt; 标记。无论如何,OP 确实说过 “我所知道的关于我所说的“我不知道的一些文本”的文本是它不包含 &lt;pre&gt;&lt;/pre&gt;。”
  • @Merlin 因为 5 是字符串 "&lt;pre&gt;" 的长度。 String#indexOf(String) 返回子字符串 开始的字符串中的索引, 所以我需要添加子字符串的长度以跳过它。
【解决方案4】:

这里有一个简单的解决方案:

private List<String> getText(String text){

    List<String> result = new ArrayList<String>();

    while(true){
        int indexStart = text.indexOf("<pre>");
        int indexEnd = text.indexOf("</pre>");
        if(indexStart >= 0 && indexEnd >= 0 && indexEnd > indexStart){
            result.add(text.substring(indexStart + 5, indexEnd));
            text = text.substring(indexEnd + 6);
        }
        else{
            break;
        }

    }
    return result;
}

请记住,您可以将此函数更改为更通用,例如将字符串作为参数传递给搜索并动态计算子字符串偏移量。我不建议你使用正则表达式,因为你可能有这样的字符串:

<pre>text<pre>more text</pre>some more text</pre>

带有嵌套的“pre”标签。

【讨论】:

  • 为什么 while(true) 让你如此震惊?
  • 你为什么用while(true)你能解释一下吗?
  • 你循环直到你的程序调用break指令退出循环,在这种情况下,它是当没有更多的打开和关闭“pre”出现时。
  • 虽然 (true) 就我而言是不好的做法,并且可能会造成混淆。 (一个例子)。至少你应该使用 while (!done)。此外,您在 if 中的条件不需要第二次检查,因为如果 indexEnd > indexStart 它肯定会大于 0。
  • 但是为什么一定要在result.add(text.substring(indexStart + 5, indexEnd)); text = text.substring(indexEnd + 6);中使用+ 5+ 6
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
相关资源
最近更新 更多