【问题标题】:Java read part of stringJava读取部分字符串
【发布时间】:2015-03-05 07:16:48
【问题描述】:

我有这段文字:

   <message id="dsds" to="test@test.com" type="video" from="test@test"><body>TESTTESTTEST</body><active xmlns="http://jabber.org"/></message>

我想在这个字符串中获取&lt;body&gt;&lt;/body&gt; 的部分。

在java中,我正在搜索并找到split,但它不能解决我的问题。如何在java中获取&lt;body&gt;&lt;/body&gt;之间的文本?

【问题讨论】:

  • 你想解析 XML 吗?
  • 你想要字符串的哪一部分?
  • @JamesFox 可能取决于。 :)
  • @詹姆斯福克斯;在 我想得到。 @Patryk;不,它不是 xml,它是我的字符串数据。
  • 看看:jsoup.org 这是一个 java html 解析器。

标签: java string javabeans


【解决方案1】:

最好使用 SAXParserDocumentBuilder 之类的解析器。您可以准确地获取标签并处理数据。当您有许多标签要处理时,它们会特别方便。

下面是一个使用 Parser 读取 body 标签的例子:

        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();
        DefaultHandler handler = new DefaultHandler(){

            String body = "";
            boolean isBody = false;

            @Override
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

                if (qName.equalsIgnoreCase("body")) {
                    isBody = true;
                }
            }

            @Override
            public void characters(char[] ch, int start, int length) throws SAXException {
                if (isBody) {
                    body = new String(ch, start, length);
                    System.out.println("body : " + body);
                }
            }

            @Override
            public void endElement(String uri, String localName, String qName) throws SAXException {
                if (qName.equalsIgnoreCase("body")) {
                    isBody = false;
                }
            }
        };

        saxParser.parse(new InputSource(new StringReader("<message id=\"dsds\" to=\"test@test.com\" type=\"video\" from=\"test@test\"><body id=\"dd\">TESTTESTTEST</body><active xmlns=\"http://jabber.org\"/></message>")), handler);

【讨论】:

    【解决方案2】:

    像这样使用正则表达式:(适用于&lt;body&gt;asas asasa &lt;/body&gt; 以及&lt;body&gt; &lt;/body&gt;

    public static void main(String[] args) {
        String s = "<message id=\"dsds\" to=\"test@test.com\" type=\"video\" from=\"test@test\"><body>TESTTESTTEST</body><active xmlns=\"http://jabber.org\"/></message>";
        Pattern p = Pattern.compile("<body.*>(.*?)</body>");
        Matcher m = p.matcher(s);
        while (m.find()) {
            System.out.println(m.group(1));
        }
    }
    

    O/P:

    TESTTESTTEST
    

    【讨论】:

    • 你在回答之前看过答案了吗?与我的答案相同,但 9 分钟后!:)
    • @FarhangAmary - 您的回答是否适用于我提供的输入?像&lt;body&gt;asas asasa &lt;/body&gt; 这样的输入。请检查。另外,我的 regex 是不同的。如果这有帮助,我看到了您的回答并同意与 Thilo。
    • 好吧,你的正则表达式有问题......它包含奇数数量的引号。据我所知,如果正文标签包含空格(&lt;body &gt;)或属性,它也会失败。
    • @Tom - 已更正.. 是一个错字。谢谢.. :).. 你能给我一个可能失败的示例输入吗?。
    • @TheLostMind 检查我对最后一条评论的编辑:P。我已经注意到了:)。
    【解决方案3】:

    使用 regx 包:

        String htmlString = "<message id=\"dsds\" to=\"test@test.com\" type=\"video\" from=\"test@test\"><body>TESTTESTTEST</body><active xmlns=\"http://jabber.org\"/></message>";
        String bodyText="";
        Pattern p = Pattern.compile("<body.*>(.*?)</body.*>");
        Matcher m = p.matcher(htmlString);
    
        if (m.find()) {
            bodyText = m.group(1);
        }
        System.out.println(bodyText);
    

    输出: TESTTESTTEST

    【讨论】:

    • 警告:如果 body 标签有任何属性(或其中只有空格),则不起作用。
    • @Thilo 然后她/他可以在模式中使用 (.*?) 而不是 (\\S+)
    【解决方案4】:

    在这种特定情况下,我建议您使用带有 Matcher 的正则表达式

    可能的解决方案: Java regex to extract text between tags

    【讨论】:

    • 您应该在答案中包含链接的基本部分。如果链接无效,您的回答将毫无意义,应该避免这种情况。
    • 该链接指向可能重复的问题/解决方案。我应该在我的答案中包含来自另一个 Stack Overflow 答案的“基本部分”吗?
    • 要么,要么将此问题标记为您找到的问题的可能重复项(最后一种方法更好)。
    • 好的,太好了。谢谢!
    【解决方案5】:

    你可以这样写代码-

    String s = "<message id=\"dsds\" to=\"test@test.com\" type=\"video\" from=\"test@test\"><body>TESTTESTTEST</body><active xmlns=\"http://jabber.org\"/></message>";//Use '/' character as escape for "
            int firstIndex = s.indexOf("<body>");
            int lastIndex = s.indexOf("</body>");
            System.out.println(s.substring(firstIndex+6, lastIndex));
    

    它会打印出预期的结果。

    【讨论】:

      【解决方案6】:

      已经给出了通过正则表达式解决它的答案(尽管 XML 解析器可能是更好的选择)。

      给出一个简单的建议来修改上述解决方案中提出的正则表达式:

      Regex proposed: (<body.*>(.*?)</body.*>) => This regex is greedy. 
      Non greed regex: <body[^>]*>(.*?)</body[^>]*>
      

      你可以让它不贪婪,这将导致运行时间的改善。原始正则表达式的问题是 .* 将继续匹配到字符串的末尾,然后它会回溯。 “[^>]”一看到右尖括号就会停止。我进行了一个简单的测试,比较了这两个正则表达式。贪婪的人花费的时间是非贪婪者的 3 倍。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-07-07
        • 1970-01-01
        • 2012-12-04
        • 1970-01-01
        • 2022-01-24
        • 1970-01-01
        • 1970-01-01
        • 2010-11-30
        相关资源
        最近更新 更多