Java操作HTML格式字符串的标签和属性

539 查看

在使用Editor(所见即所得编辑器)的时候,有时候可能会碰到需要在后台修改编辑器的内容,而且这些内容还都是HTML格式的数据,这个时候如果需要定位到某个标签的话就比较困难,毕竟是后台语言,不像前端的js一样可以在页面上直接取到某个标签,今天就分析一下使用Java如何操作HTML格式的字符串。

首先需要创建一个Patten类对象,表示需要匹配的规则。

javaString regxpForEmbedTag = "<\\s*embed\\s+([^>]*)\\s*/>";
Pattern pattern = Pattern.compile(regxpForEmbedTag);

比如,这里是匹配embed标签的规则,在编辑器里面视频生成的格式就是这个标签(现在有些编辑器可能不是了),compile方法还可以给第二个参数,可以传Pattern.CASE_INSENSITIVE进去,这样匹配规则就不区分大小写了。

然后调用matcher方法,传入待匹配内容,得到Matcher对象。

javaString content="<embed height=\"400\ width=\"480\" autostart=\"false\" src=\"http://localhost:8080/uploadFile/test.mp4\"/>";
Matcher matcher = pattern.matcher(content);

调用find方法,如果能匹配到则返回true,否则返回false,根据业务需求这里可以添加判断;

javaboolean result = matcher.find();

如果返回的是true,这时候调用group方法,可以获取到匹配到的字符串,

javaString embedStr = matcher.group(1);

这里embedStr的内容是height=\"400\ width=\"480\"" autostart=\"false\" src=\"http://localhost:8080/uploadFile/test.mp4\",不包括匹配规则的内容。

group方法必须在find方法调用之后,否则会报错,group也可以不传参数得到结果跟参数为0是一样的,这里参数的意思为:把正则表达式按照()分组,序号从1开始,在当前匹配到字符串中获取指定的分组匹配到的内容,这说起来有点拗口,比如上面的正则表达式为<\\s*embed\\s+([^>]*)\\s*/>,则可以用的参数只有0和1(如果传入的参数大于分组的序号则会报异常),在执行完matcher.find()之后,使用group()group(0)得到的结果是
<embed height=\"400\ width=\"480\" autostart=\"false\" src=\"http://localhost:8080/uploadFile/test.mp4\"/>
而如果使用group(1)则得到的结果为
height=\"400\ width=\"480\" autostart=\"false\" src=\"http://localhost:8080/uploadFile/test.mp4\"

内容需要匹配多次则可以循环调用find()方法。

如果我们现在要把width这个属性修改为100%,可以这样做

javaString regxpForWidth = "width=\"([^\"]+)\"";
Matcher matcherForWidth = Pattern.compile(regxpForWidth).matcher(embedStr);
if (matcherForWidth.find()){
    StringBuffer temp = new StringBuffer();
    matcher.appendReplacement(temp, "width=\"100%\"");
    matcher.appendTail(temp);
}

这里通过appendReplacement方法,把匹配到的内容替换成指定的字符串,注意这里替换的时候,被替换的内容是包含匹配规则的,所以在这里需要自己加上匹配规则的内容,也就是width="",appendReplacement方法有两个参数,第一个参数用来存放替换后的字符串,类型为StringBuffer,第二个参数为替换的目标值,这里在执行完appendReplacement方法之后,temp的值为height=\"400\ width=\"100%\",temp等于匹配到的字符串之前的所有内容加上被匹配后的内容,但是这里丢失了后面的内容,所以最后我们执行了appendTail方法,可以把匹配到的字符串之后的所有内容添加到temp中。

下面是一个简单的替换例子:

javaimport java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) {
        String content = "<span>这是内容开始</span><br />"
                + "<embed src=\"http://localhost:8080/uploadFile/video/1111111111.mp4\""
                + " autostart=\"false\" WIDTH=\"480\" height=\"400\" /><br />"
                + "<span>这是内容中间</span><br />"
                + "<embed src=\"http://localhost:8080/uploadFile/video/2222222222.mp4\""
                + " autostart=\"false\" WIDTH=\"480\" height=\"400\" /><br />"
                + "<span>这是内容结尾</span>";
        String regxpForEmbedTag = "<\\s*embed\\s+([^>]*)\\s*/>";
        Matcher matcher = Pattern.compile(regxpForEmbedTag).matcher(content);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String contentTemp = matcher.group(1);
            contentTemp = replaceContentByPartten(contentTemp,
                    "src=\"([^\"]+)\"",
"src=\"http://localhost:8080/uploadFile/test.mp4\"");
            contentTemp = replaceContentByPartten(contentTemp,
                    "width=\"([^\"]+)\"", "width=\"100%\"");
            matcher.appendReplacement(sb, "<video controls=\"controls\" "+ contentTemp + "></video>");
        }
        matcher.appendTail(sb);
        System.out.println(sb.toString());
    }

    public static String replaceContentByPartten(String content,
            String partten, String target) {
        Matcher matcher = Pattern.compile(partten, Pattern.CASE_INSENSITIVE).matcher(content);
        if (matcher.find()) {
            StringBuffer temp = new StringBuffer();
            matcher.appendReplacement(temp, target);
            matcher.appendTail(temp);
            return temp.toString();
        } else {
            return content;
        }
    }
}