1

我的 xml 文件看起来像:

<?xml version="1.0" encoding="UTF-8"?>
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output indent="yes"/>
    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
                <meta charset="UTF-8" content="text/html" http-equiv="Content-Type"/>
            </head>
            <body>


<div>&nbsp;</div>

            Hello body content !!

            </body>
        </html>
    </xsl:template>
    <xsl:template name="br-replace">
        <xsl:param name="word"/>
        <xsl:choose>
            <xsl:when test="contains($word,'&#xA;')">
                <xsl:value-of select="substring-before($word,'&#xA;')"/>
                <br xmlns="http://www.w3.org/1999/xhtml"/>
                <xsl:call-template name="br-replace">
                    <xsl:with-param name="word" select="substring-after($word,'&#xA;')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$word"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="format-date">
        <xsl:param name="word"/>
        <xsl:value-of select="substring($word, 1, 10)"/>
    </xsl:template>
</stylesheet>

我正在尝试将其分为三个部分:

  1. 之前的文字<body>
  2. 之间的文字<body> and </body>
  3. 之后的文字</body>

Java代码:

Matcher before = Pattern.compile("(.*?)<body>", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE)
                .matcher(input);
        String beforeStr = null;
        if (before.find()) {
            beforeStr = before.group(1);
        }

        Matcher after = Pattern.compile("</body>(.*?)", Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE)
                .matcher(input);
        String afterStr = null;
        if (after.find()) {
            afterStr = after.group(1);
        }

        Matcher body = Pattern.compile("<body>(.*?)</body>",
                Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(input);
            String bodyStr = null;
        if (body.find()) {
            bodyStr= body.group(1);
        }

知道为什么 String 'afterStr' 为空,模式有问题吗?

4

2 回答 2

3

非贪婪的量词,没有正确的东西。

"</body>(.*?)"
           ^matches as little as possible. In this case, 0 characters.

只需使用贪婪匹配:

</body>(.*)

以上将做你想要的。

于 2012-11-15T10:22:55.117 回答
1

indexOf如果您打算以文本方式而不是使用 XML 解析器来执行此操作,那么使用and不是更容易substring吗?正则表达式是错误的工具,但如果您要使用错误的工具,那么可以选择更好的错误工具。:-)

将您的代码与此进行比较(假设input是字符串):

int indexOfBodyStart = input.indexOf("<body>");
int indexOfBodyEnd   = input.indexOf("</body>");
String beforeBody    = input.substring(0, indexOfBodyStart);
String body          = input.substring(indexOfBodyStart + 6, indexOfBodyEnd);
String afterBody     = input.substring(indexOfBodyEnd + 7);

与正则表达式解决方案相比,这不会或多或少地失败。(例如,如果文本<body>出现在实际正文之前或正文</body>结尾之前的引号内,则两种解决方案都将失败。)

标记此 CW 是因为您特别询问了正则表达式。

于 2012-11-15T10:27:30.830 回答